Django查询聚合upvotes的向后关系

时间:2013-10-18 16:44:19

标签: django django-models django-queryset

我有两种模式:

Base_Activity:
    some fields

User_Activity:
    user = models.ForeignKey(settings.AUTH_USER_MODEL)
    activity = models.ForeignKey(Base_Activity)
    rating = models.IntegerField(default=0) #Will be -1, 0, or 1

现在,我想查询Base_Activity,并在顶部对具有最高级别相应的用户活动的项目进行排序。我想做类似下面的查询,但=1部分显然无效。

activities = Base_Activity.objects.all().annotate(
    up_votes = Count('user_activity__rating'=1),
).order_by(
    'up_votes'
)

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:1)

您不能像这样使用Count,因为错误消息显示:

  

SyntaxError:keyword不能是表达式

Count的参数必须是一个简单的字符串,例如user_activity__rating

我认为一个好的选择可以是同时使用AvgCount

activities = Base_Activity.objects.all().annotate(
    a=Avg('user_activity__rating'), c=Count('user_activity__rating')
).order_by(
    '-a', '-c'
)

rating=1次活动最多的项目应该具有最高的平均值,而在具有相同平均值的用户中,活动最多的项目将列在更高的位置。

如果您要排除有downvotes的项目,请务必在filter之后添加相应的excludeannotate操作,例如:

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'
)

<强>更新

要获得所有项目,由他们的赞成商订购,无视downvotes,我认为唯一的方法是使用原始查询,如下所示:

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,则可以使用{{1}获取其表名称}。

我在sqlite3数据库上测试了这个查询,我不确定Rating._meta.db_table表达式是否适用于所有DBMS。顺便说一句,我有一个完美的Django网站进行测试,我也使用upvotes和downvotes。我使用一个非常相似的模型来计算upvotes和downvotes,但我按SUM值stackoverflow样式对它们进行排序。如果您有兴趣,siteopen-source