2009-06-29 15 views
44

Ho una manciata di record che vorrei ordinare in base a un valore calcolato. Avuto la risposta over here ... in questo modo:django - converte una lista in una serie di query

sorted(Profile.objects.all(), key=lambda p: p.reputation) 

su una classe profilo come questo:

class Profile(models.Model): 

    ... 

    @property 
    def reputation(self): 
     ... 

Purtroppo la vista generica si aspetta un oggetto set di query e genera un errore se lo do una lista .

C'è un modo per fare questo che restituisce un set di query

o ...

Posso convertire un elenco ad un set di query in qualche modo? Impossibile trovare qualcosa di simile nei documenti django.

Sto sperando di non denormalizzare i dati, ma credo che lo farò se devo.

Aggiornamento/Risposta:

sembra che l'unico modo per ottenere un set di query posteriore è se è possibile ottenere tutta la tua logica nelle query SQL.

Quando ciò non è possibile, (credo) è necessario denormalizzare i dati

+2

Non è una domanda migliore "Come posso passare una lista (o un dizionario) ad una vista generica"? Presumo che, se l'hai risolto, non importa se lo hai fatto convertendo in un queryset o no ... –

+0

sì ... lo è, ma volevo solo sapere se c'era un modo semplice per convertirlo in un queryset prima di andare a bifare le viste generiche;) Mod – Jiaaro

+2

, questo non è un duplicato. È una domanda diversa a cui la risposta è: "non puoi farlo, quindi devi fare qualcos'altro". Quel "qualcos'altro" è descritto nell'altra domanda. – Jiaaro

risposta

21

v'è alcun punto nella conversione di un elenco di dati di nuovo a una query. Un oggetto query non contiene mai dati; rappresenta solo una query al database. Dovrebbe recuperare di nuovo tutto se hai fatto il tuo elenco a una query, e questo sarebbe ridondante e molto cattivo dal punto di vista delle prestazioni.

Cosa si può fare:

  • Descrivere come il campo reputation viene calcolato; è probabilmente possibile ordinare i dati nel database in qualche modo.
  • Modificare la vista per non richiedere un oggetto query. Se è necessario fare ulteriori filtraggi, ecc., Questo dovrebbe essere fatto prima di qualsiasi ordine, poiché l'ordinamento richiederà meno tempo con meno voci (e meno dati verranno recuperati dal database.) Quindi potresti inviare l'oggetto query filtrato all'ordinamento funzione appena prima di inviarlo al modello (che non dovrebbe importa se si tratta di una query o un elenco.)
+2

la reputazione è una proprietà, non un campo ... quindi non è valido – Jiaaro

+1

Bene in questo caso, è necessario archiviarlo come campo (i dati ridondanti non sono sempre negativi se aiutano le prestazioni, anche nei database normalizzati) o dovrebbe ordinare da qualcos'altro. Presumo che si tratti di un campo calcolato o unito, e puoi ordinare anche quelli con il modello di database Django. – Blixt

+0

ha appena avuto un'idea ... poiché la vista generica vuole fare un qualche tipo di filtro, perché non faccio solo l'ordinamento con un tag di modello? – Jiaaro

70

Ok ... questo post è ormai vecchio, ma quello che si potrebbe fare è ottenere tutte le ids di gli oggetti nella lista, quindi eseguire un model.objects.filter(pk__in=list_of_ids)

+1

Questo è molto lento per le raccolte di grandi dimensioni, ma era prezioso nella situazione limitata in cui avevo bisogno per risolvere rapidamente un problema. Ti consente di utilizzare i metodi QuerySet sugli elenchi di oggetti, che possono essere utili per il codice succinto. –

+17

Lo svantaggio di questo è che non manterrà l'ordinamento originale – yprez

+1

Questo ha funzionato bene per un prototipo veloce, ma di certo non consiglio di farlo in produzione, per i motivi specificati da @Blixt. – kqr

Problemi correlati