как добавить дни в поле даты аннотации django из уже построенной аннотации

#python #django #django-models #django-orm #python-dateutil

#python #django #django-модели #django-orm #python-dateutil

Вопрос:

моя модель выглядит так

 class Model(models.Model):
    user_id = models.ForeignKey()
    date = models.DateField()
    field1 = models.FloatField()
    field2 = models.FloatField()
 

У меня есть следующий набор запросов

 queryset = Model.objects.filter(user_id__exact=5) 
                       .annotate(weekstartdate=Trunc('date', 'week')) 
                       .values('weekstartdate') 
                       .annotate(avg_field1=Avg('field1')) 
                       .annotate(avg_field2=Avg('field2')) 
                       .order_by('-weekstartdate')
 

который работает отлично. теперь я хочу добавить поле weekenddate в вышеуказанный набор запросов, который имеет дату = weekstartdate 6 дней. Я добавил нижеприведенную строку к приведенному выше запросу

 .annotate(weekenddate=Trunc('date', 'week')   timedelta(days=7), output_field=DateField())
 

но он жалуется :-

Ошибка типа: QuerySet.annotate() получил невыражения: <django.db.models .поля.Поле даты>

Относительный импорт

 from django.db.models import Avg, Q
from django.db.models.functions import Trunc
from django.db.models import DateTimeField, ExpressionWrapper, F, DateField
 

Примечание :-
Простой цикл for после набора запросов — это не то, что я ищу, потому что после назначения поля вручную фильтр набора запросов все еще извлекает запрос из старого набора запросов из-за лени набора запросов.
Если ответ может быть в relativedelta библиотеки dateutil, это было бы намного лучше.

Ответ №1:

Вам нужно использовать ExpressionWrapper его.

 YourModel.objects.annotate(
    weekenddate=models.ExpressionWrapper(
        Trunc('date', 'week')   timedelta(days=7),
        output_field=models.DateField(),
    ),
)