Подтвердить что ты не робот

Django Query с использованием .order_by() и .latest()

У меня есть модель:

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

   class Meta:
      get_latest_by = 'creation_date'

У меня был запрос на мой взгляд, который сделал следующее:

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

И потом мне захотелось instances.latest(), но это не дало бы мне правильный экземпляр, на самом деле это дало мне первый экземпляр. Только когда я установил order_by в -creation_date или фактически удалил order_by из запроса, .latest() дайте мне правильный экземпляр. Это также происходит, когда я проверяю это вручную, используя оболочку python manage.py вместо представления.

Итак, что я сделал сейчас, в Model Meta я перечислил order_by = ['creation_date'] и не использовал это в запросе, и это работает.

Я бы ожидал, что .latest() всегда будет возвращать самый последний экземпляр, основанный на поле (дата) (время). Может ли кто-нибудь сказать мне, исправляет ли это, что .latest() ведет себя странно, когда вы используете order_by в запросе?

4b9b3361

Ответ 1

Я бы ожидал .latest(), чтобы всегда возвращать самый последний экземпляр, основанный на поле (дата) (время).

В документации говорится, что

Если ваша модель Meta указывает get_latest_by, вы можете оставить аргумент field_name до latest(). По умолчанию Django будет использовать поле, указанное в get_latest_by.

Все это означает, что когда вы стреляете MyModel.objects.latest(), вы получите последний экземпляр, основанный на поле даты/времени. И когда я проверил ваш код с использованием данных примера, он действительно сделал.

И потом мне понадобилось instance.latest(), но это не дало бы мне правильный экземпляр, на самом деле это дало мне первый экземпляр.

Вы неправильно поняли, как работает latest(). Когда вызывается в MyModel.objects, он возвращает последний экземпляр в таблице. При вызове запроса, latest вернет первый объект в наборе запросов. Ваш запрос состоял из всех экземпляров MyModel, упорядоченных по creation_date в порядке возрастания. Естественно тогда, что latest в этом запросе должен возвращать первую строку набора запросов. Это, кстати, самая старая строка в таблице.

Одним из способов лучшего понимания является просмотр запроса, запущенного для latest.

Случай 1:

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

Отпечатки:

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

Обратите внимание на упорядочение с помощью creation_date DESC и предложения LIMIT. Первое имеет значение get_latest_by, а последнее - вклад latest.

Теперь, случай 2:

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

печатает

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

Обратите внимание, что порядок изменился на creation_date ASC. Это результат явного order_by. LIMIT приклеивается к эру, позже любезно latest.

Давайте также рассмотрим случай 3: где вы явно указываете field_name для objects.latest().

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

показывает

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

Ответ 2

Я предполагаю, что это известная ошибка ошибка в Django, которая была исправлена ​​после публикации версии 1.3.

Ответ 3

Это сработало для меня

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