Django中的复杂排序

时间:2009-12-26 21:17:25

标签: sql django postgresql

所以我要拉一个链接列表,我试图按人气排序这些链接。我正在使用黑客新闻算法:

Y Combinator's Hacker News:
Popularity = (p - 1) / (t + 2)^1.5

Votes divided by age factor.
Where

p : votes (points) from users.
t : time since submission in hours.

p is subtracted by 1 to negate submitter's vote.
Age factor is (time since submission in hours plus two) to the power of 1.5.factor is (time since submission in hours plus two) to the power of 1.5.

我在MySQL和PHP框架中使用

命令完成了这项工作
(SUM(votes.karma_delta) - 1) / POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5) DESC

现在我正在使用PostgreSQL和Django。我知道这个确切的SQL可能不会工作,但我可以稍后进行转换。我遇到的问题是我不知道如何在Django中获得如此复杂的order_by。我的观点很完美:

popular_links = Link.objects.select_related().annotate(karma_total = Sum('vote__karma_delta'))

如果我不需要,我真的不想通过使用原始sql来解决这个问题。

总结我的问题:如何在Django中创建复杂的order_by?

修改

会有分页,我真的只想对我拉的条目进行排序。在Python中实际进行排序是否更好?

2 个答案:

答案 0 :(得分:5)

没有干净的方法,但在自定义SQL中使用extra():

popular_links = Link.objects.select_related().annotate(karma_total = Sum('vote__karma_delta'))
popular_links = popular_links.extra(
    select = {'popularity': '(karma_total - 1) / POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5)',},
    order_by = ['-popularity',]
)

答案 1 :(得分:0)

如果您打算完整地列出整个列表(例如,您不是仅使用前10个条目),那么您可以在Python中进行排序。