Django ORM:如何使用带注释字段的过滤器进行汇总?

时间:2019-09-23 14:11:14

标签: django django-orm

我具有统计信息视图,可以在某些基本查询集的不同过滤器上计算多个count

qs = Model.onjects.filter(...).annotate(a=...)
a = qs.filter(Q(a__lt=5)).count()
b = qs.filter(Q(a__lt=10)).count()  # this is just an example, real filters are more complex
...

但是每个计数都会对数据库进行单独的查询,我想对其进行优化。我尝试了aggregation

qs.aggregate(
  a=Count('a', filter=Q(a__lt=5)), 
  b=Count('a', filter=Q(a__lt=10)),
)

,但出现错误:django.db.utils.OperationalError: (1054, "Unknown column '__col2' in 'field list'")。我什至不知道这个__col2的来源。

聚集似乎不适用于注释,因为当我在count.filter中使用常规模型字段而不是注释字段a时,一切都很好。

1 个答案:

答案 0 :(得分:0)

如果您使用的是Django 2.2,则您的方法应该可以使用,如here所述。您可能应该如图所示,依靠'pk',不确定是否可以依靠注释本身:

qs.aggregate(
    a=Count('pk', filter(Q(a__lt=5)),
    b=Count('pk', filter(Q(a__lt=10))
)

如果您使用的是Django 1.11,则上述方法不起作用,因为Count将始终返回1,而忽略过滤器。您应该使用Case ... When

qs.aggregate(
    a=Sum(
        Case(When(a__lt=5, then=1),
             output_field=IntegerField())
    ),
    b=Sum(
        Case(When(a__lt=10, then=1),
             output_field=IntegerField())
    )
)