我目前正在尝试为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,但调用只是进入无限循环。
答案 0 :(得分:7)
这就是django annotate生成sql代码的方式:它执行所有必要的连接,然后在所有用户字段上进行分组,与注释函数聚合(在您的情况下计数)。因此,它会将用户与他们所有的指南相关联,然后与所有新闻相关,然后只计算每个用户生成的行数。
如果可以,您应该使用raw querysets或extra
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(存储的函数/过程)和原始查询。