Django queryset count с нулем

У меня есть эта модель Django :

class Survey(models.Model):

    call = models.OneToOneField(Call, null=True, related_name='survey', on_delete=models.CASCADE)
    service = models.ForeignKey(Service, related_name='survey', null=True, on_delete=models.CASCADE)
    when_start = models.DateTimeField()
    when_end = models.DateTimeField()

Я хотел бы получить количество звонков на одну услугу в течение временного интервала

Я попробовал это :

start = datetime.datetime(2024, 6, 17, 0, 0)
end = datetime.datetime(2024, 6, 17, 23, 59, 59)
services = <QuerySet [<Service: S1>, <Service: S2>, <Service: S3>]>

Survey.objects.filter(service__in=services, when_start__range=(start, end)).values('service__name').annotate(nb=Count('call'))

result : <QuerySet [{'service__name': 'S1', 'nb': 50}, {'service__name': 'S2', 'nb': 119}]>

Но я хотел бы иметь следующее (0 для службы "S3"):

<QuerySet [{'service__name': 'S1', 'nb': 50}, {'service__name': 'S2', 'nb': 119}, {'service__name': 'S3', 'nb': 0}]]>

Я прочитал несколько заметок, в которых говорилось о "Coalesce", но я не могу правильно его использовать

Вместо этого отметьте службу:

from django.db.models import Count, Q

services.objects.annotate(
    nb=Count('survey__call', filter=Q(survey__when_start__range=(start, end)))
)

Вы также получаете Service объекты с атрибутом .nb, поэтому не только имя Service.

работает ли она?

objs = Survey.objects.filter(when_start__range=(start, end))
a = objs.filter(service={service}).values('service__name').annotate(nb=Count('call'))
b = objs.filter(service={service1}).values('service__name').annotate(nb=Count('call'))
...
z = objs.filter(service={service3}).values('service__name').annotate(nb=Count('call'))

result = a|b|...|z
Вернуться на верх