Django如何按投票支持率/上下票差值对模型查询结果排序
按净得票排序实现
你原代码的问题在于直接对多对多字段做Sum运算,没有先统计两个字段的关联用户数量,需要先通过Count分别统计点赞、点踩的总人数,再计算差值:
from django.db.models import F, Count, IntegerField words = Word.objects.filter(name__iexact='test').annotate( # 统计点赞总数,distinct避免多对多聚合重复计数 up_count = Count('upvotes', distinct=True), # 统计点踩总数 down_count = Count('downvotes', distinct=True), # 计算净得票:点赞数减点踩数 net_votes = F('up_count') - F('down_count', output_field=IntegerField()) # 按净得票倒序,得分高的在前 ).order_by('-net_votes')
按投票支持率排序实现
支持率计算公式为 点赞数/(点赞数+点踩数),需要额外处理无任何投票时分母为0的情况:
from django.db.models import F, Count, Case, When, FloatField, Value words = Word.objects.filter(name__iexact='test').annotate( up_count = Count('upvotes', distinct=True), down_count = Count('downvotes', distinct=True), total = F('up_count') + F('down_count'), # 计算支持率,无投票时默认支持率为0,可根据需求调整默认值 support_rate = Case( When(total=0, then=Value(0.0)), default = F('up_count') * 1.0 / F('total'), output_field = FloatField() ) # 按支持率倒序,支持率高的在前 ).order_by('-support_rate')
如果需要前端切换两种排序逻辑,只要根据传入的参数修改order_by对应的字段即可。
内容的提问来源于stack exchange,提问作者nadermx
相关产品推荐
相关产品推荐

