Django聚合和注释行为比较

时间:2017-07-18 09:03:03

标签: python django

我试图使用带注释的值来使用F表达式过滤查询集,但事实证明它不像我期望的那样。

我正在尝试过滤查询集qs中的对象,其属性some_prop是该查询集的最大值。例如:

set(qs.values_list('some_prop', flat=True))

会输出:

set([1, 3, 5, 7, 9])

我的目标是用值9来过滤qs,这是最大值。我可以使用聚合轻松实现这一目标:

max_prop = qs.aggregate(max_prop=Max('some_prop'))['max_prop']
qs.filter(some_prop=max_prop)

但我想在单个查询中压缩此行为,因此我使用了注释而不是聚合:

qs.annotate(max_prop=Max('some_prop')).filter(some_prop=F('max_prop'))

然而,这并未显示相同的行为。这实际上只是按所有some_prop值而不是最大值进行过滤。

我错过了什么?必须有一些我从注释和聚合功能中误解的东西。

1 个答案:

答案 0 :(得分:0)

由于您的注释不会从一对多关系中获取值,因此相关对象集合中的最大值将被注释到与该集合相关的对象,Max(对于每个对象) )只接受一个值 - some_prop - 并附加到查询集中的每个对象;这与直接访问/过滤some_prop没有什么不同:

  

当指定annotate()子句时,QuerySet中的每个对象   将使用指定的值进行注释。

对于单个表,您需要先聚合以获取最大值,然后对该值进行过滤。