Obtener el último registro de un conjunto de consultas

Respuestas:

81

EDITAR: ahora tienes que usar Entry.objects.latest('pub_date')


Simplemente podría hacer algo como esto, usando reverse():

queryset.reverse()[0]

Además, tenga cuidado con esta advertencia de la documentación de Django:

... tenga en cuenta que reverse()generalmente solo se debe llamar en un QuerySet que tiene un orden definido (por ejemplo, cuando se consulta contra un modelo que define un orden predeterminado, o cuando se usa order_by()). Si no se define tal orden para un determinado QuerySet, invocarlo reverse()no tiene ningún efecto real (el orden no estaba definido antes de la llamada reverse()y permanecerá indefinido después).

jujule
fuente
2
como se dice en los documentos de django,: "tenga en cuenta que reverse () generalmente solo se debe llamar en un QuerySet que tiene un orden definido (por ejemplo, cuando se consulta contra un modelo que define un orden predeterminado, o cuando se usa order_by ()). Si no tal orden está definido para un QuerySet dado, llamar a reverse () no tiene ningún efecto real (el orden no estaba definido antes de llamar a reverse (), y permanecerá sin definir después) ".
jujule
6
2017 y las respuestas aceptadas están desactualizadas ahora. Como se muestra a continuación, debe usar queryset.last ().
wobbily_col
134

Documento de Django :

latest(field_name=None) devuelve el último objeto de la tabla, por fecha, utilizando el field_name proporcionado como el campo de fecha.

Este ejemplo devuelve la última entrada de la tabla, según el pub_datecampo:

Entry.objects.latest('pub_date')
Asinox
fuente
5
Esta es la mejor forma de hacerlo. Además, "Si el Meta de su modelo especifica get_latest_by, puede dejar el argumento field_name en latest ()" según los documentos.
Fredrik Möllerstrand
50

La forma más sencilla de hacerlo es:

books.objects.all().last()

También usa esto para obtener la primera entrada así:

books.objects.all().first()
haky_nash
fuente
16
books.objects.last() y books.objects.first()debería hacer el truco.
chandan
Esta debería ser la respuesta aceptada junto con XYZ.objects.first()y XYZ.objects.last()
slajma
Creo que el estilo de Arnaud P es el más apropiado. Esto, si no se equivoca, descomprimirá todos los elementos en la base de datos donde el último extrae la última consulta de base de datos.
Larcho
33

Django> = 1.6

Se agregaron los métodos QuerySet first () y last () que son métodos convenientes que devuelven el primer o último objeto que coincide con los filtros. Devuelve Ninguno si no hay objetos que coincidan.

panchicore
fuente
32

Para obtener el primer objeto:

ModelName.objects.first()

Para obtener los últimos objetos:

ModelName.objects.last()

Puedes usar el filtro

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

Esto funciona para mi.

Ravi Kumar
fuente
6

Cuando el conjunto de consultas ya está agotado, puede hacer esto para evitar otra sugerencia de db:

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

No lo use try...except....
Django no lanza IndexErroren este caso.
Lanza AssertionErroro ProgrammingError(cuando ejecuta python con la opción -O)

jifeng.yin
fuente
1
Suponiendo que su conjunto de consultas ya está ordenado, esta debería ser la "respuesta principal", porque es la única solución que no llega a la base de datos nuevamente.
David D.
4

Si usa django 1.6 y versiones posteriores, es mucho más fácil ahora que se introdujo la nueva api:

Model.object.earliest()

Dará último () con dirección inversa.

PD: sé que es una pregunta anterior, publico como si, en el futuro, alguien aterrizara en esta pregunta, conozca esta nueva característica y no termine usando el método anterior.

Mutante
fuente
3
de los documentos: earliest () y latest () requieren un parámetro field_name o 'get_latest_by' en el modelo
panchicore
1

Puede usar Model.objects.last()o Model.objects.first(). Si no orderingse define, el conjunto de consultas se ordena en función de la clave principal. Si desea un conjunto de consultas de comportamiento de pedidos, puede consultar los dos últimos puntos.

Si está pensando en hacer esto, Model.objects.all().last()recuperar el último y Model.objects.all().first()recuperar el primer elemento en un conjunto de consultas o usarlo filterssin pensarlo dos veces. Luego, vea algunas advertencias a continuación.

La parte importante a tener en cuenta aquí es que si no ha incluido ninguno orderingen su modelo, los datos pueden estar en cualquier orden y tendrá un último o primer elemento aleatorio que no se esperaba.

P.ej. Supongamos que tiene un modelo nombrado Model1que tiene 2 columnas idy item_count10 filas con id 1 a 10. [No hay ningún orden definido]

Si obtiene Model.objects.all (). Last () de esta manera, puede obtener cualquier elemento de la lista de 10 elementos. Sí, es aleatorio ya que no hay un orden predeterminado.

Entonces, ¿qué puede hacerse?

  1. Puede definir en orderingfunción de cualquier campo o campos de su modelo. También tiene problemas de rendimiento, compruébalo también. Ref: Aquí
  2. O puede usarlo order_bymientras busca. Me gusta esto:Model.objects.order_by('item_count').last()
Roshan Dawande
fuente
-5

La forma más sencilla, sin tener que preocuparse por el orden actual, es convertir el QuerySet en una lista para que pueda usar la indexación negativa normal de Python. Al igual que:

list(User.objects.all())[-1]
Josh Ourisman
fuente
2
Esto consultará TODOS los objetos de la base de datos y luego tomará el primero
warvariuc
¡Buen punto! Obviamente no pensé en eso. ¡La respuesta .reverse () (seleccionada actualmente) es el camino correcto a seguir!
Josh Ourisman