Django,如何在单个查询集中进行多个注释

时间:2015-06-17 19:19:25

标签: python django count django-queryset annotate

我目前正在尝试为Django中的User模型注释两个不同数量的喜欢。

这是我用来返回所需querySet的代码

def get_top_user(self):
    return User.objects. \
        annotate(guide_like=Count('guidelike')).\
        annotate(news_like=Count('newslike')).\
        values_list('first_name', 'last_name', 'guide_like','news_like').\
        order_by('-guide_like')

但是,querySet返回[“Bob”,“Miller”,612072,612072]。正如你所看到的,Django取两个注释值并将它们相乘,这就是我得到612072的原因。

有没有办法在单个querySet中调用多个注释而不会获得这些相乘的值。

编辑:还尝试在查询结尾处添加distinct()或在每个计数中添加distinct = True,但调用只是进入无限循环。

1 个答案:

答案 0 :(得分:7)

这就是django annotate生成sql代码的方式:它执行所有必要的连接,然后在所有用户字段上进行分组,与注释函数聚合(在您的情况下计数)。因此,它会将用户与他们所有的指南相关联,然后与所有新闻相关,然后只计算每个用户生成的行数。

如果可以,您应该使用raw querysetsextra Queryset方法。 E.g:

User.objects.all().extra(select={
    'guide_likes': 'select count(*) from tbl_guide_likes where user_id=tbl_users.id',
    'news_like': 'select count(*) from tbl_news_likes where user_id=tbl_users.id'
}).\
values_list('first_name', 'last_name', 'guide_like','news_like')

为了获得更大的灵活性,您可以使用select_params方法的extra参数来提供表格的名称(您可以通过Model._meta获得)。顺便说一句,这是非常不方便和hackish方法。 你的逻辑迟早会变得更加复杂,然后你应该将它从python代码中删除到sql(存储的函数/过程)和原始查询。