Rozważ proste modele Django Event
i 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)
W zapytaniu dotyczącym wydarzeń można łatwo opisać całkowitą liczbę uczestników:
events = Event.objects.all().annotate(participants=models.Count('participant'))
Jak dodawać adnotacje z liczbą przefiltrowanych uczestników is_paid=True
?
Muszę odpytywać wszystkie zdarzenia niezależnie od liczby uczestników, np. Nie muszę filtrować według wyników z adnotacjami. Jeśli są 0
uczestnicy, w porządku, potrzebuję tylko 0
wartości z adnotacjami.
Przykład z dokumentacji nie działa tutaj, ponieważ wyklucza obiektów z kwerendy zamiast opisywania ich 0
.
Aktualizacja. Django 1.8 ma nową funkcję wyrażeń warunkowych , więc teraz możemy zrobić tak:
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()
)))
Aktualizacja 2. Django 2.0 ma nową funkcję agregacji warunkowej , zobacz zaakceptowaną odpowiedź poniżej.
aggregate
pokazane jest tylko użycie. Czy przetestowałeś już takie zapytania? (Nie mam i chcę wierzyć! :)