2009-12-26 102 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