什么是在QuerySet中获得排名的最有效方法?

时间:2012-06-21 00:21:47

标签: python mysql django

我正在尝试有效地对QuerySet进行排名(保持它为QuerySet以便我可以保留过滤器和order_by函数),但似乎找不到任何其他方式然后迭代查询集并增加排名。如果我不需要,我不想在我的模型中添加等级。

我知道如何通过SQL查询获取我需要的值,但似乎无法将其转换为Django:

SET @rank = 0, @prev_val = NULL;
SELECT rank, name, school, points FROM
    (SELECT @rank := IF(@prev_val = points, @rank, @rank+1) AS rank, @prev_val := points, points, CONCAT(users.first_name, ' ', users.last_name) as name, school.name as school
    FROM accounts_userprofile
        JOIN schools_school school ON school_id = school.id
        JOIN auth_user users ON user_id = users.id
    ORDER BY points DESC) as profile
ORDER BY rank DESC

我发现,如果我迭代遍历QuerySet并手动添加'rank'然后进一步过滤结果,我的'rank'将消失 - 除非将其转换为列表(这使得过滤和排序有点痛)。有没有其他方法可以考虑添加我的QuerySet的排名?有没有办法我可以做上面的查询并获得一个带有过滤器和order_by函数的QuerySet仍然完好无损?我目前正在使用带有Django的jQuery DataTables来生成带分页的排行榜(这就是我需要保留过滤和order_by的原因)。

提前致谢!对不起,如果我没有正确发布我的问题 - 任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:0)

我自己没有用过它,但我很确定你可以用extra()方法做到这一点。

答案 1 :(得分:0)

查看原始SQL我的逻辑中没有看到任何特殊内容。您只是枚举由点计数的连接上的所有SQL行,计数器为1,同时将相同的点值折叠到相同的排名。

我的建议是编写一个使用raw()或extra()方法的自定义管理器。在您的经理中,您将在所有模型实例上使用python的枚举作为先前由points排序的排名。当然,如果它们具有相同的点数,则必须保持点的当前最大值并覆盖枚举返回的值。请查看here以获取类似内容的示例。

然后你可以这样做:

YourQuerySet.objects.with_rankings().all()