你不能这样使用Count
,因为错误消息说:
SyntaxError:关键字不能是表达式
的参数Count
必须是一个简单的字符串,例如user_activity__rating
.
我认为一个很好的选择是使用Avg
andCount
一起:
activities = Base_Activity.objects.all().annotate(
a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).order_by(
'-a', '-c'
)
活跃度最高的项目rating=1
应该具有最高的平均数,在平均数相同的用户中,活跃度最高的用户会排名靠前。
如果您想排除有否决票的项目,请确保在 之后添加适当的filter
orexclude
操作annotate
,例如:
activities = Base_Activity.objects.all().annotate(
a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).filter(user_activity__rating__gt=0).order_by(
'-a', '-c'
)
更新
要获得所有项目,按他们的赞成票排序,不考虑反对票,我认为唯一的方法是使用原始查询,如下所示:
from django.db import connection
sql = '''
SELECT o.id, SUM(v.rating > 0) s
FROM user_activity o
JOIN rating v ON o.id = v.user_activity_id
GROUP BY o.id ORDER BY s DESC
'''
cursor = connection.cursor()
result = cursor.execute(sql_select)
rows = result.fetchall()
注意:不要硬编码模型的表名,而是从模型中获取表名,例如,如果您的模型被调用Rating
,那么您可以使用Rating._meta.db_table
.
我在 sqlite3 数据库上测试了这个查询,我不确定SUM
那里的表达式在所有 DBMS 中都有效。顺便说一句,我有一个完美的 Django 站点来测试,我也使用 upvotes 和 downvotes。我使用一个非常相似的模型来计算赞成票和反对票,但我按sum
值排序它们,stackoverflow 样式。该网站是开源的,如果您有兴趣。