2009-12-26 7 views
7

Donc je tire une liste de liens et j'essaye de trier ces liens par popularité. J'utilise l'algorithme Nouvelles Hacker:Commande complexe dans 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. 

J'accompli cela dans MySQL et un framework PHP en utilisant une commande par

(SUM(votes.karma_delta) - 1)/POW((TIMESTAMPDIFF(HOUR, links.created, NOW()) + 2), 1.5) DESC 

Maintenant, je suis en utilisant PostgreSQL et Django. Je sais que ce SQL exact ne fonctionnera probablement pas mais je peux faire la conversion plus tard. Le problème que je rencontre est que je ne sais pas comment obtenir un order_by aussi complexe dans Django. Mon point de vue est parfait:

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

Et je ne veux pas vraiment muck que par l'aide de sql brut si je n'ai pas.

Pour résumer ma question: comment puis-je créer un order_by complexe dans Django?

EDIT

Il y aura et je veux en page vraiment que pour trier les entrées que je tire. Est-il préférable de faire ce tri en Python?

Répondre

5

Pas de manière propre, mais en utilisant() supplémentaire avec votre SQL personnalisé:

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

semble qu'il devrait y avoir un wy pour faire cela avec des expressions F? – JudoWill

+0

@JudiWIll Qu'est-ce que ça veut dire? – TheLizardKing

+0

Cela me jette une exception: 'Pris une exception lors du rendu: colonne" karma_total "n'existe pas LIGNE 1: SELECT ((karma_total - 1)) AS" popularité "," links_link "." Id ... ' – TheLizardKing

0

Si vous voulez tirer la liste entière de toute façon (c'est-à-dire, vous ne prenez pas seulement les 10 premières entrées, par exemple), alors vous pouvez faire le tri en Python.

+0

Je dois souligner sans doute que j'ai des plans paginations. – TheLizardKing

Questions connexes