3

我正在尝试有效地对 QuerySet 进行排名(将其保留为 QuerySet 以便我可以保留 filter 和 order_by 函数),但似乎找不到任何其他方法来遍历 QuerySet 并增加排名。如果不需要,我不想为我的模型添加排名。

我知道如何通过 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 并手动添加了“排名”,然后进一步过滤了结果,我的“排名”就会消失 - 除非将它变成一个列表(这使得过滤和排序有点痛苦)。有没有其他方法可以为我的 QuerySet 添加排名?有什么办法可以进行上述查询并获得一个带有 filter 和 order_by 功能的 QuerySet 仍然完好无损?我目前正在使用带有 Django 的 jQuery DataTables 来生成带有分页的排行榜(这就是我需要保留过滤和 order_by 的原因)。

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

4

2 回答 2

0

查看您的原始 SQL,我看不出您的逻辑有什么特别之处。您只是枚举连接上的所有 SQL 行,按点排序,计数器从 1 开始,同时将相同的点值折叠到相同的等级。

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

然后你可以做类似的事情:

YourQuerySet.objects.with_rankings().all()
于 2012-06-21T12:23:26.780 回答
0

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

于 2012-06-21T02:21:02.907 回答