Аннотируйте QuerySet с максимальным полем даты и датой, созданной вручную
У меня следующая модель:
class Item(models.Model):
last_used = models.DateTimeField()
created_at = models.DateTimeField()
Сейчас я пытаюсь посмотреть среднее "время жизни" предметов в месяц. Время жизни - это сколько дней в среднем используются предметы. Я могу рассчитать общее среднее значение следующим образом:
from django.db.models import IntegerField, F, Avg
from django.db.models.functions import Cast, ExtractDay, TruncDate
items = Item.objects.annotate(days_used=Cast(ExtractDay(TruncDate(F('last_used')) - TruncDate(F('created_at'))), IntegerField())+1)
avg = items.aggregate(Avg('days_used'))['days_used__avg']
Теперь, когда я хочу вычислить это значение за месяц, я хотел бы аннотировать запрос новым полем, которое является максимальным из created_at или начала рассматриваемого месяца. Это нужно для того, чтобы максимальное значение времени жизни для всех месяцев было равно количеству дней в этом месяце
Есть функция Greatest
, которая, как мне кажется, может быть использована для этого, но я не уверен как. Если предположить, что нас интересует декабрь 2021 года, вот что у меня есть на данный момент:
from django.db.models.functions import Greatest
target_month = 12
items = items.annotate(created_max=Greatest(TruncDate(F('created_at')), TruncDate(F(timezone.datetime(2021, target_month, 1)))
Но использование timezone.datetime
приводит к ошибке:
AttributeError: объект 'datetime.datetime' не имеет атрибута 'split'
ПРИМЕЧАНИЕ: Я знаю, что last_used
может привести к превышению количества дней, но это другой вопрос, который мы решаем.
Вам следует использовать выражение django.db.models.Value вместо django.db.models.F для постоянных значений.
from django.db.models.functions import Greatest
target_month = 12
items = items.annotate(created_max=Greatest(TruncDate(F('created_at')), TruncDate(Value(timezone.datetime(2021, target_month, 1)))