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)
)
Вернуться на верх