consideri semplici modelli Django Event
e Participant
:Come filtrare gli oggetti per l'annotazione del conteggio in Django?
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)
E 'facile per annotare eventi di query con il numero totale dei partecipanti:
events = Event.objects.all().annotate(participants=models.Count('participant'))
Come annotare con conteggio dei partecipanti filtrata da is_paid=True
?
Ho bisogno di interrogare tutti gli eventi indipendentemente dal numero di partecipanti, ad es. Non ho bisogno di filtrare per risultato annotato. Se ci sono 0
partecipanti, va bene, ho solo bisogno di 0
nel valore annotato.
Il example from documentation non funziona qui, perché esclude gli oggetti dalla query invece di annotarli con 0
.
Aggiornamento . Django 1.8 dispone di nuove conditional expressions feature, così 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()
)))
Update 2. Django 2.0 ha una nuova funzione di Conditional aggregation, vedi the accepted answer sotto.
Questo è fantastico! :) – rudyryk
BTW, non esiste un tale esempio dal collegamento della documentazione, viene mostrato solo l'utilizzo "aggregato". Hai già provato queste domande? (Non ho e voglio crederci! :) – rudyryk
Ho. Lavorano. In realtà ho colpito una patch strana in cui una subquery vecchia (super-complicata) ha smesso di funzionare dopo l'aggiornamento a Django 2.0 e sono riuscito a sostituirlo con un conteggio filtrato super-semplice. Esiste un migliore esempio in-doc per le annotazioni, quindi lo inserirò ora. – Oli