你不能像错误消息所说的那样使用Count:
语法错误:关键字不能是表达式
Count 的参数必须是一个简单的字符串,比如user_activity__rating。
我认为将Avg 和Count 一起使用是一个不错的选择:
activities = Base_Activity.objects.all().annotate(
a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).order_by(
'-a', '-c'
)
rating=1 活动最多的项目的平均值应该最高,在具有相同平均值的用户中,活动最多的用户会排名靠前。
如果您想排除有否决票的项目,请确保在annotate 之后添加适当的filter 或exclude 操作,例如:
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 样式。 site 是 open-source,如果你有兴趣的话。