Ottieni l'ultimo record in un set di query


Risposte:


81

EDIT: ora devi usare Entry.objects.latest('pub_date')


Potresti semplicemente fare qualcosa di simile, usando reverse():

queryset.reverse()[0]

Inoltre, fai attenzione a questo avviso dalla documentazione di Django:

... nota che reverse()generalmente dovrebbe essere chiamato solo su un QuerySet che ha un ordinamento definito (ad esempio, quando si interroga su un modello che definisce un ordinamento predefinito, o quando si usa order_by()). Se nessun tale ordinamento è definito per un dato QuerySet, invocarlo reverse()non ha alcun effetto reale (l'ordinamento era indefinito prima della chiamata reverse()e rimarrà indefinito in seguito).


2
come detto in django docs,: "nota che reverse () dovrebbe generalmente essere chiamato solo su un QuerySet che ha un ordine definito (ad esempio, quando si interroga su un modello che definisce un ordinamento predefinito, o quando si usa order_by ()). Se no tale ordinamento è definito per un dato QuerySet, chiamare reverse () su di esso non ha alcun effetto reale (l'ordinamento era indefinito prima di chiamare reverse (), e rimarrà indefinito in seguito). "
jujule

6
2017 e le risposte accettate non sono aggiornate ora. Come mostrato di seguito, dovresti usare queryset.last ().
wobbily_col

134

Django Doc :

latest(field_name=None) restituisce l'ultimo oggetto nella tabella, per data, utilizzando il field_name fornito come campo della data.

Questo esempio restituisce l'ultima voce nella tabella, in base al pub_datecampo:

Entry.objects.latest('pub_date')

5
Questo è il modo migliore per farlo. Inoltre, "Se il Meta del tuo modello specifica get_latest_by, puoi lasciare l'argomento field_name a latest ()" come da documenti.
Fredrik Möllerstrand

50

Il modo più semplice per farlo è:

books.objects.all().last()

Lo usi anche per ottenere la prima voce in questo modo:

books.objects.all().first()

16
books.objects.last() e books.objects.first()dovrebbe fare il trucco.
chandan

Questa dovrebbe essere la risposta accettata insieme a XYZ.objects.first()e XYZ.objects.last()
slajma

Penso che la via di Arnaud P sia quella più appropriata. Questo, se non errato, decomprimerà tutti gli elementi nel DB in cui il successivo estrae l'ultima query DB utilizzando.
Larcho

33

Django> = 1.6

Aggiunti i metodi QuerySet first () e last () che sono metodi convenienti che restituiscono il primo o l'ultimo oggetto che corrisponde ai filtri. Restituisce Nessuno se non ci sono oggetti corrispondenti.


32

Per ottenere il primo oggetto:

ModelName.objects.first()

Per ottenere gli ultimi oggetti:

ModelName.objects.last()

Puoi usare il filtro

ModelName.objects.filter(name='simple').first()

Questo funziona per me.


6

Quando il set di query è già esaurito, puoi farlo per evitare un altro suggerimento db -

last = queryset[len(queryset) - 1] if queryset else None

Non usare try...except....
Django non lancia IndexErrorin questo caso.
Lancia AssertionErroro ProgrammingError(quando esegui python con l'opzione -O)


1
Supponendo che il tuo set di query sia già ordinato, questa dovrebbe essere la "risposta migliore", perché è l'unica soluzione che non colpisce nuovamente il database.
David D.

4

Se si utilizza django 1.6 e versioni successive, è molto più semplice ora che è stata introdotta la nuova API -

Model.object.earliest()

Fornirà latest () con direzione inversa.

ps - Conosco la sua vecchia domanda, postando come se qualcuno dovesse atterrare su questa domanda, conoscono questa nuova funzionalità e non finiscono per usare il vecchio metodo.


3
from docs: earliest () e latest () richiedono un parametro field_name o "get_latest_by" nel modello
panchicore

1

Puoi usare Model.objects.last()o Model.objects.first(). Se no orderingè definito, il set di query viene ordinato in base alla chiave primaria. Se vuoi impostare la query sul comportamento dell'ordine, puoi fare riferimento agli ultimi due punti.

Se stai pensando di fare questo, Model.objects.all().last()per recuperare l'ultimo e Model.objects.all().first()per recuperare il primo elemento in un set di query o utilizzare filterssenza pensarci due volte. Quindi vedere alcuni avvertimenti di seguito.

La parte importante da notare qui è che se non ne hai incluso nessuno orderingnel tuo modello, i dati possono essere in qualsiasi ordine e avrai un ultimo o un primo elemento casuale che non era previsto.

Per esempio. Supponiamo che tu abbia un modello denominato Model1che ha 2 colonne ide item_countcon 10 righe con ID da 1 a 10. [Non è definito alcun ordine]

Se prendi Model.objects.all (). Last () in questo modo, puoi ottenere qualsiasi elemento dalla lista di 10 elementi. Sì, è casuale in quanto non esiste un ordine predefinito.

Allora cosa si può fare?

  1. È possibile definire in orderingbase a qualsiasi campo o campi del modello. Ha anche problemi di prestazioni, per favore controlla anche quello. Rif: qui
  2. OPPURE puoi usare order_bydurante il recupero. Come questo:Model.objects.order_by('item_count').last()

-5

Il modo più semplice, senza doversi preoccupare dell'ordinamento corrente, è convertire il QuerySet in un elenco in modo da poter utilizzare la normale indicizzazione negativa di Python. Così:

list(User.objects.all())[-1]

2
Questo interrogherà TUTTI gli oggetti dal DB e poi prenderà il primo
warvariuc

Buon punto! Ovviamente non ci ho pensato. La risposta .reverse () (attualmente selezionata) è la strada giusta da percorrere!
Josh Ourisman
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.