答案 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。很可能这个查询可以用更好的方式重写,但我现在还没有想法......