Django подсчитывает связанный объект с определенным условием

#django #django-models #django-annotate #django-aggregation

#django #django-модели #django-аннотировать #django-агрегация

Вопрос:

У меня есть классы этой модели в моем приложении django:

 class Ad(models.Model):
    ...

class Click:
    time = models.DateTimeField(auto_now_add=True)
    ip = models.GenericIPAddressField()
    ad = models.ForeignKey(
        to=Ad,
        related_name='views',
        on_delete=CASCADE
    )

class View:
    time = models.DateTimeField(auto_now_add=True)
    ip = models.GenericIPAddressField()
    ad = models.ForeignKey(
        to=Ad,
        related_name='views',
        on_delete=CASCADE
    )
  

Предположим, у меня есть набор Ad запросов объектов. Я хочу прокомментировать количество кликов для каждого добавления, которое произошло за 12-13 часов (мы могли бы использовать range поиск). Сначала я сделал это так:

 query.filter(clicks__time__hour__range=[12, 13]).annotate(views_count=Count('views',distinct=True), clicks_count=Count('clicks', distinct=True))
  

но те объявления, у которых нет кликов в этом диапазоне, будут исключены из запроса таким образом, но мне нужно, чтобы они присутствовали в конечном запросе.

Есть ли какой-нибудь правильный способ сделать это, возможно, с помощью условных выражений Django?

Ответ №1:

Согласно документам, вы должны иметь возможность выполнять фильтр в Count совокупности.

 from django.db.models import Count, Q
query.annotate(
    views_count=Count('views',distinct=True),
    clicks_count=Count('clicks', distinct=True, filter=Q(time__hour__range=[12, 13])),
)