Джанго сумма временных разниц от полей модели

#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()
        )
    )
)