Django sql排序依据
我在这件事上真的很挣扎。 我需要能够排序,我的用户的意见收到的正面投票数 我有一个表userprofile、一个表comment和一个表likeComment。 表注释具有指向其用户创建者的外键,而表likeComment具有指向注释的外键。 要获取用户获得的赞成票数,请执行以下操作:Django sql排序依据,sql,database,django,django-queryset,Sql,Database,Django,Django Queryset,我在这件事上真的很挣扎。 我需要能够排序,我的用户的意见收到的正面投票数 我有一个表userprofile、一个表comment和一个表likeComment。 表注释具有指向其用户创建者的外键,而表likeComment具有指向注释的外键。 要获取用户获得的赞成票数,请执行以下操作: LikeComment.objects.filter(Q(type = 1), Q(comment__user=user)).count() 现在,我希望能够将所有用户按投票率最高的用户进行排序。我该怎么做?我
LikeComment.objects.filter(Q(type = 1), Q(comment__user=user)).count()
现在,我希望能够将所有用户按投票率最高的用户进行排序。我该怎么做?我试着使用extra和JOIN,但没有成功
谢谢你models.py
class UserProfile(models.Model):
.........
def like_count(self):
LikeComment.objects.filter(comment__user=self.user, type=1).count()
views.py
def getRanking( anObject ):
return anObject.like_count()
def myview(request):
users = list(UserProfile.objects.filter())
users.sort(key=getRanking, reverse=True)
return render(request,'page.html',{'users': users})
听起来像是要对批注执行筛选:
class User(models.Model):
pass
class Comment(models.Model):
user = models.ForeignKey(User, related_name="comments")
class Like(models.Model):
comment = models.ForeignKey(Comment, related_name="likes")
type = models.IntegerField()
users = User \
.objects \
.all()
.extra(select = {
"positive_likes" : """
SELECT COUNT(*) FROM app_like
JOIN app_comment on app_like.comment_id = app_comment.id
WHERE app_comment.user_id = app_user.id AND app_like.type = 1 """})
.order_by("positive_likes")
这可能是解决这类问题的最简单方法,但子查询的性能几乎不如连接,因此如果用户很多,您可能会发现需要更好的性能
因此,重新使用Timmy的模型:
类Usermodels。模型:
通过
类模型。模型:
user=models.ForeignKeyUser,related\u name=comments
类Likemodels.Model:
comment=models.foreignkeycoment,related\u name=likes
类型=models.IntegerField
您想要的查询在SQL中如下所示:
选择app_user.id,COUNTapp_like.id作为总喜欢数
来自应用程序用户
左外连接应用程序注释
在app_user.id=app_comment.user_id上
左外连接应用程序_like
在app_comment.id=app_like.comment_id和app_like.type=1上
按app_user.id分组
按总数排序
如果实际用户模型中的字段不止id,那么需要将它们全部包含在SELECT和GROUP BY子句中
Django的对象关系映射系统没有提供一种表达此查询的方法。据我所知,如果有人告诉我,我会非常高兴的-它只支持跨一个连接的聚合,而不支持此处的跨两个连接的聚合。但是,当ORM不能胜任此工作时,您可以始终运行,如下所示:
sql='1〕
选择app_user.id,COUNTapp_like.id作为总喜欢数
如上所述
'
对于user.objects.rawsql中的用户:
打印user.id,user.total\u
我相信这可以通过Django的queryset实现:
User.objects.filter(comments__likes__type=1)\
.annotate(lks=Count('comments__likes'))\
.order_by('-lks')
这里唯一的问题是,此查询将错过喜欢0的用户。来自@gareth rees、@timmy omahony和@Catherine的代码也将包含排名为0的用户。此解决方案是正确的,但如果网站每年获得大量用户或请求,则会产生高负载minute@Igor如果您愿意,有许多方法可以减少这种负载。他可以使用分页,每页加载10个用户。他还可以获得前10名或20名用户,其他用户可以搜索。问题有很多解决方案,如果你真的想要的话。我一开始是这样做的,但我觉得额外的更快^^谢谢你,因为你解决了我的另一个问题^^谢谢蒂米,我发疯了,可以进行查询了!现在我这样做了,我得到了一个DB错误:在或接近SELECT行8的语法错误:SELECT COUNT*来自axiom_alto_likecommentI,我得到了!因为annotate的原因,我无法使用annotate和extra,所以我将所有内容都放入extra ^^^再次感谢