Considere modelos simples do Django Event
e Participant
:
class Event(models.Model):
title = models.CharField(max_length=100)
class Participant(models.Model):
event = models.ForeignKey(Event, db_index=True)
is_paid = models.BooleanField(default=False, db_index=True)
É fácil anotar a consulta de eventos com o número total de participantes:
events = Event.objects.all().annotate(participants=models.Count('participant'))
Como fazer anotações com a contagem de participantes filtrada por is_paid=True
?
Preciso consultar todos os eventos, independentemente do número de participantes, por exemplo, não preciso filtrar por resultado anotado. Se houver 0
participantes, tudo bem, eu só preciso de um 0
valor anotado.
O exemplo da documentação não funciona aqui, porque exclui objetos da consulta em vez de anotá-los 0
.
Atualizar. O Django 1.8 possui um novo recurso de expressões condicionais , então agora podemos fazer o seguinte:
events = Event.objects.all().annotate(paid_participants=models.Sum(
models.Case(
models.When(participant__is_paid=True, then=1),
default=0,
output_field=models.IntegerField()
)))
Atualização 2. O Django 2.0 possui o novo recurso de agregação condicional , veja a resposta aceita abaixo.
aggregate
uso é mostrado. Você já testou essas consultas? (Eu não tenho e quero acreditar!)