考虑一下简单的Django型号EventParticipant:

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'))

How to annotate with count of participants filtered by 100?

我需要查询all events,而不考虑参与者的数量,例如,我不需要根据带注释的结果进行筛选.如果有0个参与者,没关系,我只需要0个注释值.

example from documentation在这里不起作用,因为它从查询中排除对象,而不是用0注释它们.

Update. 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()
    )))

Update 2. Django 2.0具有新的Conditional aggregation特性,请参见下面的the accepted answer.

Update 3.美元换Django 3.x,请给我check this answer below美元.

推荐答案

Django 2.0中的Conditional aggregation允许您进一步减少过go 的faff数量.这也将使用Postgres的filter逻辑,它比求和运算要快一些(我见过20-30%这样的数字流传).

不管怎么说,在你的 case 中,我们看到的是这样简单的东西:

from django.db.models import Q, Count
events = Event.objects.annotate(
    paid_participants=Count('participants', filter=Q(participants__is_paid=True))
)

文档中有一个单独的部分,大约filtering on annotations个.这和条件聚合是一样的,但更像我上面的例子.不管怎样,这都比我以前做的那些粗糙的子查询健康得多.

Django相关问答推荐

自定义公钥打破Django管理内联逻辑

如何根据属性的 Select 对查询集进行排序

使用django直接计算geohash而不创建模型

如何在Django中将可选参数传递给视图?

Django:添加第二个';详细';用于检索额外信息的视图

Django中每个类型/代理的最新行

Django 仅预取相关模型的最新对象

防止 django 将_id附加到外键字段

Django:无法从另一个应用程序导入模型

文档中的 Mongoengine creation_time 属性

如何运行克隆的 Django 元素?

如何在django中生成临时文件然后销毁

virtualenv(python3.4), pip install mysqlclient 错误

如何在python中遍历httprequest post变量

是否可以将 FastAPI 与 Django 一起使用?

django.core.exceptions.ImproperlyConfigured:请求设置 USE_I18N,但未配置设置

这是验证 Django 模型字段的方法吗?

为整个结果集向 Django Rest Framework 结果添加额外数据

Django:根据自定义函数过滤查询

想要在 Django 测试中禁用信号