从方法订购

时间:2010-11-24 19:20:54

标签: python django function sql-order-by

2 个答案:

答案 0 :(得分:2)

您可以在查询返回结果后对列表进行排序:

article_votes = sorted(article.votes, key=lambda a: a.votes())

sorted获取一个列表并对其进行排序。您可以提供一个自定义函数,它接受一个元素并返回在比较元素时使用的值。 lambda a: a.votes()是一个匿名函数,它接受一篇文章并返回文章的投票数。

如果您要检索所有文章,这个解决方案没有任何缺点。另一方面,如果您只想通过投票获得前10篇文章,那么您将从数据库中提取所有文章,而不是让数据库进行排序,而只返回前十名。与纯SQL解决方案相比,这是从数据库中检索更多数据。

答案 1 :(得分:0)

这是Ned Batchelder建议的更快版本 - 因为它在数据库中进行计数:

articles = list(Article.objects.annotate(upvote_num=models.Count('upvotes'), downvote_num=models.Count('downvotes')))
articles.sort(key=lambda a: a.upvotes - a.downvotes)

您也可以在数据库中完全执行此操作:

articles = Article.objects.raw("""
    SELECT DISTINCT id from articles_article,
    COUNT(DISTINCT upv) AS num_upvotes,
    COUNT(DISTINCT downv) AS num_downvotes,
    (num_upvotes - num_downvotes) AS score

    INNER JOIN [article_user_upvotes_m2m_table_name] AS upv
    ON upv.article_id = id

    INNER JOIN [article_user_downvotes_m2m_table_name] AS downv
    ON downv.article_id = id

    GROUP BY id
    ORDER BY score
""")

- 但我不确定双连接在你的情况下是不是一个好主意。另外,我不确定是否需要所有这些DISCTINCT。很可能这个查询可以用更好的方式重写,但我现在还没有想法......