注释不同的 Django 查询集不再使用不同的查询集
Posted
技术标签:
【中文标题】注释不同的 Django 查询集不再使用不同的查询集【英文标题】:Annotating on a distinct Django Queryset is no longer using the distinct queryset 【发布时间】:2022-01-23 07:26:55 【问题描述】:我有一个查询,我正在尝试注释字段 tail_tip
的每个值的计数。我的原始查询过滤了相关表,因此有必要使用 distinct()。
我不完全确定如何描述,但是当我注释不同的查询时,查询不再不同。这是我在 shell 中使用的查询。
// Without distinct()
Ski.objects.filter(published=True, size__size__in=[178, 179, 180, 181, 182, 183, 184]).count()
// 318
skis = Ski.objects.filter(published=True, size__size__in=[178, 179, 180, 181, 182, 183, 184]).distinct()
skis.count()
// 297
skis.values('tail_tip').order_by('tail_tip').annotate(count=Count('tail_tip'))
// <QuerySet ['tail_tip': 'flat', 'count': 99, 'tail_tip': 'full_twin', 'count': 44, 'tail_tip': 'partial_twin', 'count': 175]>
// total count = 318
鉴于skis
已经是distinct()
我不知道为什么当我对其进行注释时,总计数等于非明确查询。
【问题讨论】:
【参考方案1】:尝试添加distinct=True
:
skis.values('tail_tip').order_by('tail_tip').annotate(count=Count('tail_tip', distinct=True))
【讨论】:
在<QuerySet ['tail_tip': 'flat', 'count': 1, 'tail_tip': 'full_twin', 'count': 1, 'tail_tip': 'partial_twin', 'count': 1]>
中添加不同的结果【参考方案2】:
假设名为Size
和Ski
的相关表具有一对多的关系。这可以通过这种方式完成:
ski_filtered = Ski.objects.filter(
published=True,
id__in=Size.objects.values("skis__id").filter( # Maybe somethig else than `skis` here, you didn't show its model, so I couldn't know
size__in=[178, 179, 180, 181, 182, 183, 184]
)
)
skis.values('tail_tip').distinct().order_by('tail_tip').annotate(count=Count('tail_tip'))
为什么会这样:DISTINCT
不能与 annotate()
一起使用。在 django 中实现 annotate()
是用它自己的 GROUP BY
子句实现的。所以在已经 GROUP BY
-ed 的查询上应用 distinct()
是行不通的。
【讨论】:
这很有效,感谢您的解释!以上是关于注释不同的 Django 查询集不再使用不同的查询集的主要内容,如果未能解决你的问题,请参考以下文章