2009-12-26 17 views
7

Quindi sto selezionando un elenco di collegamenti e sto tentando di ordinare questi collegamenti per popolarità. Sto usando l'algoritmo di Hacker News:Ordinamento complesso in 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. 

Ho compiuto questo in MySQL e di un quadro di PHP utilizzando un ordine da parte

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

Ora sto usando PostgreSQL e Django. So che questo SQL esatto probabilmente non funzionerà, ma posso eseguire la conversione in seguito. Il problema che sto incontrando è che non so come ottenere un ordine così complesso da Django. La mia opinione è un perfetto:

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

E io in realtà non vuole letame che fino utilizzando SQL prime se non devo.

Per riassumere la mia domanda: come posso creare un ordine complesso_di Django?

EDIT

Ci saranno impaginazione e ho davvero solo voglia di ordinare le voci mi tiro. È meglio fare effettivamente questo ordinamento in Python?

risposta

5

No way pulita ma utilizzando extra() con il vostro SQL personalizzata:

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

sembra che ci dovrebbe essere una cosa da fare con le espressioni F? – JudoWill

+0

@JudiWIll Che cosa significa? – TheLizardKing

+0

Questo mi lancia un'eccezione: 'Catturato un'eccezione durante il rendering: colonna" karma_total "inesistente LINEA 1: SELECT ((karma_total - 1)) AS" popolarità "," link_link "." Id ... " – TheLizardKing

0

Se si desidera estrarre comunque l'intera lista (ovvero, non si stanno prendendo solo le prime 10 voci, ad esempio), è possibile eseguire l'ordinamento in Python.

+0

Probabilmente dovrei notare che ho piani di impaginazione. – TheLizardKing