【发布时间】:2015-08-25 11:09:35
【问题描述】:
考虑简单的 Django 模型 Event 和 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)
使用参与者总数注释事件查询很容易:
events = Event.objects.all().annotate(participants=models.Count('participant'))
如何用is_paid=True过滤的参与者数量进行注释?
无论参与者有多少,我都需要查询所有事件,例如我不需要按带注释的结果进行过滤。如果有 0 参与者,那没关系,我只需要 0 注释值。
example from documentation 在这里不起作用,因为它从查询中排除对象,而不是用 0 注释它们。
更新。 Django 1.8 有了新的conditional expressions feature,所以现在我们可以这样做:
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()
)))
更新 2。 Django 2.0 具有新的Conditional aggregation 功能,请参阅下面的the accepted answer。
更新 3。 对于 Django 3.x,请check this answer below。
【问题讨论】:
标签: python django django-models django-aggregation