Django - Аннотация Count() отдельных значений, сгруппированных по дате
У меня есть следующая модель:
class Visualization(models.Model):
....
user: FK user
start_time: DATETIME
product: FK product
....
Пример данных:
Идентификатор пользователя | Время начала | Идентификатор продукта |
---|---|---|
1 | 2021-09-07 14:03:07 | 3 |
2 | 2021-09-07 13:06:00 | 1 |
1 | 2021-09-07 17:03:06 | 1 |
4 | 2021-09-07 04:03:05 | 5 |
1 | 2021-09-07 15:03:17 | 4 |
1 | 2021-09-07 19:03:27 | 1 |
2 | 2021-09-06 21:03:31 | 3 |
1 | 2021-09-06 11:03:56 | 9 |
1 | 2021-09-06 07:03:19 | 9 |
Мне нужно получить активных пользователей за дни, активными считаются те, кто сделал хотя бы одну репродукцию, если пользователь сделал много репродукций, он все равно считается как 1.
Правильным ответом будет:
Total | Date |
---|---|
3 | 2021-09-07 |
2 | 2021-09-06 |
Сначала я делаю аннотацию Truncate of StartTime, чтобы сохранить только дату, а затем делаю Group By для этой аннотации, пока все без проблем. Проблема возникает, когда я пытаюсь подсчитать пользователей, так как у них есть повторения. Я пробовал считать по User_id с Distinct = True, но цифры все равно получаются плохие, причем с очень большой разницей. Я также пробовал группировать по user_id и периоду (аннотация Truncate StartTime), но и это не помогло
Вы можете сделать запрос типа:
from django.db.models import Count
from django.db.models.functions import TruncDate
Visualization.objects.values(
date=TruncDate('start_time')
).annotate(
total=Count('user', distinct=True)
).order_by('date')
Для дней, в которые не производилось размножение, не будет строки в QuerySet
, поэтому вам потребуется постобработка этих дат.
Вы можете использовать модификатор extra() QuerySet для запроса группировки по дате:
from django.db.models import Count
Visualization.objects.extra(
select={'start_date': 'date( start_time )'}
).values(
'start_date'
).annotate(
total=Count('user', distinct=True)
)