Personalizzazione in Django

Come si fa a definire una specifica ordinazione in Django QuerySets?

In particolare, se ho un QuerySet in questo modo: ['a10', 'a1', 'a2'].

Ordine regolare (utilizzando Whatever.objects.order_by('someField')) mi darà ['a1', 'a10', 'a2'], mentre sto cercando: ['a1', 'a2', 'a10'].

Qual è il modo corretto per definire il mio ordine di tecnica?

InformationsquelleAutor Yuval Adam | 2009-05-19

 

4 Replies
  1. 42

    Per quanto ne so io, non c’è modo di specificare database lato ordinamento in questo modo sarebbe troppo di back-end specifiche. Si potrebbe desiderare di ricorrere al buon vecchio Python ordinamento:

    class Foo(models.Model):
        name = models.CharField(max_length=128)
    
    Foo.objects.create(name='a10')
    Foo.objects.create(name='a1')
    Foo.objects.create(name='a2')
    
    ordered = sorted(Foo.objects.all(), key=lambda n: (n[0], int(n[1:])))
    print ordered # yields a1, a2, 10

    Se vi trovate bisogno di questo tipo di ordinamento di un sacco, mi consiglia di fare una custom models.Manager sottoclasse per il tuo modello che esegue l’ordine. Qualcosa come:

    class FooManager(models.Manager):
        def in_a_number_order(self, *args, **kwargs):
            qs = self.get_query_set().filter(*args, **kwargs)
            return sorted(qs, key=lambda n: (n[0], int(n[1:])))
    
    class Foo(models.Model):
        ... as before ...
        objects = FooManager()
    
    print Foo.objects.in_a_number_order()
    print Foo.objects.in_a_number_order(id__in=[5, 4, 3]) # or any filtering expression
    • A posto! Bella risposta, grazie!
    • Ricevo questo errore quando si tenta di questo metodo: : ‘Modello’ oggetto è unindexable
    • Non sorted restituire un queryset? Dato che è passato un queryset, io pensavo così, ma sto pensando che potrebbe anche essere convertiti in un elenco o qualcosa internamente per l’ordinamento, quindi che viene restituito.
    • Ho paura sorted non restituisce un queryset; è un built-in funzione python, quindi non so nulla di Django. Django querysets implementazione di python interfaccia per iterables, così sorted è in grado di lavorare su di loro perché si pensa che è appena stato superato da un elenco. Se avete bisogno di restituire un QS, per quanto ne sappia non esiste un modo semplice per creare un QS off l’elenco ordinato ritorna… È possibile un falso QS (fondamentalmente implementare la sua interfaccia), ma che può essere difficile. Ci sono molti Manager metodi che non restituiscono QS, e questa funzione di ordinamento sarebbe coerente con quelli, ho paura.
  2. 30

    @Jarret risposta (non il tipo in Python) che funziona alla grande per i casi più semplici. Non appena si dispone di un grande tavolo e voglio, dire, tirare solo la prima pagina di risultati ordinati in un certo modo, questo approccio si rompe (devi tirare ogni singola riga dal database prima di eseguire l’ordinamento). A questo punto vorrei guardare in aggiunta denormalizzato “sorta” di campo che si popola da campo “nome”, a risparmiare tempo, che è possibile ordinare il DB-livello nel solito modo.

    • +1 per affrontare i problemi relativi alle prestazioni; infatti, il suggerimento è quello che abbiamo utilizzato in alcuni dei dati utilizzati per il report, in un DB-agnostico ambiente, e abbiamo decine di milioni di righe, e posso assicurarvi che funziona bene.
  3. 0

    Dipende dalla posizione in cui si desidera utilizzarlo.

    Se si desidera utilizzare nel vostro template, vorrei suggerire di scrivere un modello-tag, che l’ordinamento per voi
    In esso, è possibile utilizzare qualsiasi algoritmo di ordinamento che si desidera utilizzare.

    In admin faccio ordinamento personalizzato, estendendo i modelli per le mie esigenze e il caricamento di un modello-tag, come descritto sopra

  4. 0

    Se si dispone di grandi insiemi di dati e, inoltre, utilizzare un SOLR backend (ad esempio con un Pagliaio):

    Utilizzare solr.ICUCollationField con il numeric=true opzione per il tipo di ordinamento dei campi. Questo consentirà di ordinare in base alla lingua e se i numeri sono presenti ordinare il numero di parte secondo numerico regole invece di stringa di ordinamento.

    Vedere:
    https://cwiki.apache.org/confluence/display/solr/Language+Analisi#LanguageAnalysis-UnicodeCollation
    http://www.solr-start.com/javadoc/solr-lucene/org/apache/solr/schema/ICUCollationField.html

Lascia un commento