2009-12-26 106 views
7

因此,我拉出链接列表,并试图按照流行度对这些链接进行排序。我现在用的黑客新闻的算法:Django中的复杂排序

 
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框架通过使用ORDER BY

(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中进行排序只是更好吗?

回答

5

没有干净的方式,但使用额外的()与您的自定义SQL:

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',] 
) 
+0

似乎应该有一个W与F表达式做这个? – JudoWill 2009-12-26 23:53:03

+0

@JudiWIll What'cha是什么意思? – TheLizardKing 2009-12-26 23:53:35

+0

这给我一个例外: '在呈现时捕获到异常:列“karma_total”不存在 LINE 1:SELECT((karma_total - 1))AS“popular”,“links_link”。“id ...' – TheLizardKing 2009-12-27 06:53:44

0

如果你打算拉整个列表(也就是说,你不是只拿前10个条目),那么你可以在Python中进行排序。

+0

我也许应该注意到,我有分页的计划。 – TheLizardKing 2009-12-26 21:39:07