简体   繁体   中英

Annotate QuerySet with the maximum of a date field and a manually created date

I have the following model:

class Item(models.Model):
    last_used = models.DateTimeField()
    created_at = models.DateTimeField()

I'm trying now to look at the average "lifetime" of items per month. Lifetime is how many days items are used, on average. I can calculate the overall average with the following:

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']

Now when I want to calculate this per month, I would like to annotate the query with a new field that is the maximum of created_at or the beginning of the month in question. This is needed so that the maximum lifetime value for all months is the number of days in that month.

There's a function, Greatest that I think could be used for this, but I'm not sure how. Assuming we're interested in December, 2021, this is what I have at the moment:

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

But using timezone.datetime is causing an error:

AttributeError: 'datetime.datetime' object has no attribute 'split'

NOTE: I'm aware that last_used may cause the value to go over the number of days but that's another issue we're tackling.

You should use django.db.models.Value expression instead of django.db.models.F for constant values.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM