使用Django ORM按计数进行过滤

11

我有一个查询,基本上是“计算类型为X的所有项,并返回存在多次的项以及它们的计数”。目前我有这个:

Item.objects.annotate(type_count=models.Count("type")).filter(type_count__gt=1).order_by("-type_count")

但它没有返回任何内容(所有项目的计数均为1)。我做错了什么?

理想情况下,应该得到以下结果:

Type
----
1
1
2
3
3
3

并返回:

Type, Count
-----------
1     2
3     3

我可以这样做,但相关的部分仅仅是有一个“项目”模型,其中包含一个“类型”字段... - Stavros Korokithakis
2个回答

25
为了统计每种类型的出现次数,您需要按type字段进行分组。在Django中,可以使用values仅获取该字段来完成此操作。因此,应该按如下方式操作:
Item.objects.values('group').annotate(
     type_count=models.Count("type")
).filter(type_count__gt=1).order_by("-type_count")

是的 - 但使用 type 而不是 group :) 它会返回类似这样的内容:[{'type': u'X', 'type_count': 2}] - 为什么我之前没有说呢 :) - bx2
我觉得你在那里是指"类型"而不是"组",当我没有使用__gt部分时它确实起作用了,但是使用__gt部分时它会抛出"dict对象没有type_count属性"的错误,这告诉我它试图将其作为列来访问... - Stavros Korokithakis
很奇怪 - 我已经检查过了,它像魔法一样运行。顺便说一下,当它在字典中说没有type_count属性时,它是指聚合生成的字典 - 它不会像访问列一样尝试访问它。结果应该像我上面写的那样。在Django shell中检查以确保。 - bx2
没错,你说得对。我忘了它被转成了一个字典,并尝试使用属性查找。现在它非常好用,谢谢!我将把这个答案标记为正确,因为我无法将其分成两个部分:( - Stavros Korokithakis

3

这是一个逻辑错误 ;)

type_count__gt=1 的意思是 type_count > 1,因此如果 count == 1,它将不会被显示 :) 请改用 type_count__gte=1 - 它的意思是 type_count >= 1 :)


是的,但你说计数器对于每个都是1 - 这就是为什么没有显示任何东西的原因 :) - bx2
有重复的类型,但所有东西的计数都是1。这是错误的,但我不知道为什么计数不正确。 - Stavros Korokithakis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接