Considere modelos simples de Django Eventy 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)
Es fácil anotar consultas de eventos con el número total de participantes:
events = Event.objects.all().annotate(participants=models.Count('participant'))
¿Cómo anotar con el recuento de participantes filtrados por is_paid=True?
Necesito consultar todos los eventos independientemente del número de participantes, por ejemplo, no necesito filtrar por resultado anotado. Si hay 0participantes, está bien, solo necesito0 valor anotado.
El ejemplo de la documentación no funciona aquí, porque excluye objetos de la consulta en lugar de anotarlos con 0.
Actualizar. Django 1.8 tiene una nueva función de expresiones condicionales , por lo que ahora podemos hacer lo siguiente:
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()
)))
Actualización 2. Django 2.0 tiene una nueva función de agregación condicional , consulte la respuesta aceptada a continuación.
aggregatese muestra el uso. ¿Ya ha probado este tipo de consultas? (¡No lo he hecho y quiero creer! :)