Я хотел бы суммировать все продолжительности события в день. Это моя модель:Агрегатная сгруппированная аннотация
class Event(models.Model):
start = models.DateTimeField()
end = models.DateTimeField()
Образец данных:
import datetime
from random import randint
for i in range(0, 1000):
start = datetime.datetime(
year=2016,
month=1,
day=randint(1, 10),
hour=randint(0, 23),
minute=randint(0, 59),
second=randint(0, 59)
)
end = start + datetime.timedelta(seconds=randint(30, 1000))
Event.objects.create(start=start, end=end)
я могу рассчитывать событие в день, как так: (я знаю extra
это плохо, но я использую 1.9 в данный момент . Когда я обновляю я перейду к использованию TruncDate
)
Event.objects.extra({'date': 'date(start)'}).order_by('date').values('date').annotate(count=Count('id'))
[{'count': 131, 'date': datetime.date(2016, 1, 1)},
{'count': 95, 'date': datetime.date(2016, 1, 2)},
{'count': 99, 'date': datetime.date(2016, 1, 3)},
{'count': 85, 'date': datetime.date(2016, 1, 4)},
{'count': 87, 'date': datetime.date(2016, 1, 5)},
{'count': 94, 'date': datetime.date(2016, 1, 6)},
{'count': 97, 'date': datetime.date(2016, 1, 7)},
{'count': 111, 'date': datetime.date(2016, 1, 8)},
{'count': 97, 'date': datetime.date(2016, 1, 9)},
{'count': 104, 'date': datetime.date(2016, 1, 10)}]
можно аннотировать добавить продолжительность:
In [3]: Event.objects.annotate(duration=F('end') - F('start')).first().duration
Out[3]: datetime.timedelta(0, 470)
Но я не могу понять, как суммировать эту аннотацию так же, как я могу подсчитывать события. Я пробовал следующее, но я получил KeyError
по длительности.
Event.objects.annotate(duration=F('end') - F('start')).extra({'date': 'date(start)'}).order_by('date').values('date').annotate(total_duration=Sum('duration'))
А если добавить duration
к статье values
тогда он больше не групп по дате.
Возможно ли это в одном запросе и без добавления поля длительности в модель?
Когда вы выполняете 'values ('date')' на этом наборе запросов, вы удаляете поле 'duration', поэтому сумма не суммируется. Что произойдет, если вы добавите 'duration' в вызов 'values ()' и затем 'order_by ('date')' после этого? Или, нужно ли вообще использовать 'values ()'? – ChidG
Привет @ChidG! (как Ze'ev?) 'values' используется для group_by - я думаю, что это необходимо. Если я добавляю 'duration' к вызову' values', он пытается группировать события вместе как «date», так и «duration», а не просто «date». –