#python #django #view #model
Вопрос:
Я пытаюсь получить сумму временных различий из полей модели в Django. Я пробовал это, но получаю пустой результат без ошибок:
model.py
class Project(models.Model):
design_start = models.DateField(editable= True, default=datetime.today, blank=True)
design_end = models.DateField(editable= True, default=datetime.today, blank=True)
class Portfolio(models.Model):
projects = models.ManyToManyField(Project)
Я пытаюсь получить общее время разработки всех проектов, вычитая design_start из design_end, а затем получая сумму всего
views.py
class DashView(generic.ListView):
context_object_name = 'project_list'
template_name = 'index.html'
queryset = Project.objects.all()
def get_context_data(self, **kwargs):
context = super(DashView, self).get_context_data(**kwargs)
context['design_time'] = Portfolio.objects.all().annotate(
design_time = ExpressionWrapper(Sum(F('projects__design_end') - F('projects__design_start')),
output_field=DurationField()),
)
return context
urls.py
urlpatterns = [
path('', views.DashView.as_view(), name='home'),
]
index.html
<h4>{{ design_time.design_time }}</h4>
Комментарии:
1.
design_time
естьQuerySet
, следовательно , нетdesign_time.design_time
, вам нужно зациклиться на этом…2. @AbdulAzizBarkat спасибо за ваш ответ. Я попробовал это:
{% for time in design_time %}{{ time }} {% endfor %}
и я получил эту ошибку: «Вы не можете использовать Sum, Avg, StdDev и дисперсию» django.db.utils. NotSupportedError: Вы не можете использовать агрегации суммы, среднего значения, StdDev и дисперсии в полях даты/времени в sqlite3, так как дата/время сохраняется в виде текста.3. Я отредактировал свой ответ на эту ошибку, проверьте.
Ответ №1:
По вашему мнению, вы пишете:
context['design_time'] = Portfolio.objects.all().annotate(design_time=...)
Здесь ваш выбор ключа не очень описателен (похоже, даже вас обмануло это ваше имя). Здесь design_time
есть QuerySet
множество Portfolio
объектов, следовательно, нет такого понятия, как design_time.design_time
. Вместо этого, если вы пройдете по циклу design_time
, вы получите Portfolio
экземпляры, которые будут снабжены design_time
комментариями к ним. Чтобы быть более описательным, сначала переименуйте этот ключ в контексте во что-то вроде:
context['portfolios'] = Portfolio.objects.all().annotate(design_time=...)
Далее в вашем шаблоне выполните цикл над этим:
{% for portfolio in portfolios %}
{{ portfolio.design_time }}
{% endfor %}
Также в своем запросе вы используете ExpressionWrapper
на Sum
, вместо этого вы должны использовать Sum
на ExpressionWrapper
:
Portfolio.objects.all().annotate(
design_time = Sum(
ExpressionWrapper(
F('projects__design_end') - F('projects__design_start'),
output_field=DurationField()
)
)
)