Django Query usando .order_by () y .latest ()

Tengo un modelo:

class MyModel(models.Model): creation_date = models.DateTimeField(auto_now_add = True, editable=False) class Meta: get_latest_by = 'creation_date' 

Tuve una consulta en mi opinión que hizo lo siguiente:

 instances = MyModel.objects.all().order_by('creation_date') 

Y luego, después, quise instances.latest() , pero no me dio la instancia correcta, de hecho, me dio la primera. Solo cuando establecí order_by en -creation_date o eliminé el order_by de la consulta, .latest() me dio la instancia correcta. Esto también sucede cuando pruebo esto manualmente usando el shell de python manage.py en lugar de en la vista.

Entonces, lo que he hecho ahora está en el Meta del modelo que he enumerado order_by = ['creation_date'] y no lo he usado en la consulta, y eso funciona.

Hubiera esperado que .latest() siempre devuelva la instancia más reciente en función de un campo (fecha) (hora). ¿Alguien podría decirme si es correcto que .latest() comporte de forma extraña cuando usa order_by en la consulta?

Hubiera esperado que .latest () siempre devuelva la instancia más reciente en función de un campo (fecha) (hora).

La documentación dice que

Si el Meta su modelo especifica get_latest_by , puede dejar el argumento field_name a latest() . Django utilizará el campo especificado en get_latest_by de forma predeterminada.

Todo lo que esto significa es que cuando MyModel.objects.latest() obtendrás la última instancia basada en el campo de fecha / hora. Y cuando probé su código usando datos de muestra, de hecho lo hizo.

Y luego, después, quise instance.latest (), pero no me dio la instancia correcta, de hecho, me dio la primera.

Has entendido mal la forma en que funciona latest() . Cuando se llama en MyModel.objects , devuelve la última instancia en la tabla . Cuando se llama en un queryset , el latest devolverá el primer objeto en el queryset . Su conjunto de consultas consistió en todas las instancias de MyModel ordenadas por creation_date en orden ascendente. Es natural que la latest versión de este conjunto de consultas devuelva la primera fila del conjunto de consultas . Esto, por cierto, es la fila más antigua de la tabla .

Una forma de obtener una mejor comprensión es ver la consulta activada para obtener la información latest .

Caso 1:

 from django.db import connection MyModel.objects.latest() print connection.queries[-1]['sql'] 

Esto imprime:

 SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM "app_mymodel" ORDER BY "app_mymodel"."creation_date" DESC LIMIT 1 

Tenga en cuenta el ordenamiento por creation_date DESC y la cláusula LIMIT . El primero es gracias a get_latest_by mientras que el segundo es la contribución de la latest .

Ahora, caso 2:

 MyModel.objects.order_by('creation_date').latest() print connection.queries[-1]['sql'] 

huellas dactilares

 SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM "app_mymodel" ORDER BY "app_mymodel"."creation_date" ASC LIMIT 1 

Tenga en cuenta que el orden ha cambiado a creation_date ASC . Este es el resultado del order_by explícito. El LIMIT se fija en la er, más tarde, cortesía.

También veamos el caso 3: donde se especifica explícitamente el nombre de campo para objects.latest() .

 MyModel.objects.latest('id') print connection.queries[-1]['sql'] 

muestra

 SELECT "app_mymodel"."id", "app_mymodel"."creation_date" FROM "app_mymodel" ORDER BY "app_mymodel"."id" DESC LIMIT 1 

Supongo que este es un error conocido en Django que se solucionó después del lanzamiento de la versión 1.3.

Esto funciono para mi

 latestsetuplist = SetupTemplate.objects.order_by('-creationTime')[:10][::1]