Considera semplici modelli 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)
È facile annotare la query sugli eventi con il numero totale di partecipanti:
events = Event.objects.all().annotate(participants=models.Count('participant'))
Come annotare con il conteggio dei partecipanti filtrati per is_paid=True
?
Ho bisogno di interrogare tutti gli eventi indipendentemente dal numero di partecipanti, ad esempio non ho bisogno di filtrare per risultato annotato. Se ci sono0
partecipanti, va bene, ho solo bisogno 0
di un valore annotato.
L' esempio della documentazione non funziona qui, perché esclude gli oggetti dalla query invece di annotarli con 0
.
Aggiornare. Django 1.8 ha una nuova funzionalità per le espressioni condizionali , quindi ora possiamo fare in questo modo:
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()
)))
Aggiornamento 2. Django 2.0 ha una nuova funzionalità di aggregazione condizionale , vedere la risposta accettata di seguito.
aggregate
viene mostrato solo l' utilizzo. Hai già testato queste domande? (Non l'ho fatto e voglio crederci! :)