Betrachten Sie einfache Django-Modelle Event
und 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 ist einfach, Ereignisabfragen mit der Gesamtzahl der Teilnehmer zu kommentieren:
events = Event.objects.all().annotate(participants=models.Count('participant'))
Wie kommentiere ich mit der Anzahl der Teilnehmer, nach denen gefiltert wurde is_paid=True
?
Ich muss alle Ereignisse unabhängig von der Anzahl der Teilnehmer abfragen , z. B. muss ich nicht nach kommentierten Ergebnissen filtern. Wenn es 0
Teilnehmer gibt, ist das in Ordnung, ich brauche nur einen 0
kommentierten Wert.
Das Beispiel aus der Dokumentation funktioniert hier nicht, da Objekte von der Abfrage ausgeschlossen werden, anstatt sie mit Anmerkungen zu versehen 0
.
Aktualisieren. Django 1.8 verfügt über eine neue Funktion für bedingte Ausdrücke. Jetzt können wir Folgendes tun:
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 verfügt über eine neue Funktion zur bedingten Aggregation (siehe die akzeptierte Antwort unten).
aggregate
Verwendung wird angezeigt. Haben Sie solche Abfragen bereits getestet? (Ich habe nicht und ich möchte glauben! :)