Django:结合来自两个过滤器查询的两个计数注释

Posted

技术标签:

【中文标题】Django:结合来自两个过滤器查询的两个计数注释【英文标题】:Django: Combine two count annotations from two filter queries 【发布时间】:2021-09-27 19:09:37 【问题描述】:

我正在根据两个不同的过滤器计算一些统计数据,但我不确定如何将这两个结果合并到一个 QuerySet 中。

我的代码如下所示:

qs1 = User.objects.filter(c1).annotate(count1=Count("id"))
qs2 = User.objects.filter(c2).annotate(count2=Count("id"))

我想创建第三个查询集qs3,它同时具有count1count2。基本上我想离开User.id,但我找不到直接的方法。

我也试过

count1 = Count('id', filter=c1)
count2 = Count('id', filter=c2)
qs3 = User.objects.annotate(count1=count1).annotate(count2=count2)

但它给了我不同的结果。

【问题讨论】:

qs1qs2 得到什么结果?每次计数不会只返回 0 或 1 吗? 不,因为我的回答中的帖子解释了 django 中的filter 有点奇怪。如果您过滤相关元素,它会与这些表进行连接,这意味着用户的 id 将出现多次,每个相关记录一次。就我而言,这正是我想要的。 【参考方案1】:

我最终解决了子查询,如the first answer here 中所述。

qs1 = User.objects.filter(c1).annotate(count=Count('id')).filter(pk=OuterRef('pk'))
qs2 = User.objects.filter(c2).annotate(count=Count('id')).filter(pk=OuterRef('pk'))
users = User.objects.annotate(
    count1=Subquery(qs1.values('count'), output_field=IntegerField()),
    count2=Subquery(qs2.values('count'), output_field=IntegerField())
)

我仍然不完全理解解决方案,因为这是我第一次看到子查询,但它似乎有效。如果有人想提供更详细的答案,我很乐意接受。

【讨论】:

以上是关于Django:结合来自两个过滤器查询的两个计数注释的主要内容,如果未能解决你的问题,请参考以下文章

Django 结合两个没有 Q 的查询

Django通过谓词和计数结果注释查询集

Django 多注解返回错误结果

结合两个查询并获得计数的总和

如何在 Django 中过滤对象以进行计数注释?

注释不同的 Django 查询集不再使用不同的查询集