Получить последнюю запись в наборе запросов

Ответы:

81

РЕДАКТИРОВАТЬ: теперь вам нужно использовать Entry.objects.latest('pub_date')


Вы можете просто сделать что-то подобное, используя reverse():

queryset.reverse()[0]

Также обратите внимание на это предупреждение из документации Django:

... обратите внимание, что reverse()обычно следует вызывать только QuerySet, который имеет определенный порядок (например, при запросе к модели, которая определяет порядок по умолчанию, или при использовании order_by()). Если такой порядок не определен для данного QuerySetобъекта, его вызов reverse()не имеет реального эффекта (порядок не был определен до вызова reverse()и останется неопределенным после).

джуджуле
источник
2
как сказано в django docs: «обратите внимание, что reverse () обычно следует вызывать только для QuerySet, который имеет определенный порядок (например, при запросе к модели, которая определяет порядок по умолчанию, или при использовании order_by ()). Если нет такой порядок определен для данного QuerySet, вызов метода reverse () для него не имеет реального эффекта (порядок не был определен до вызова функции reverse () и останется неопределенным после этого) ».
jujule
6
2017 г., а принятые ответы уже устарели. Как показано ниже, вам следует использовать queryset.last ().
wobbily_col
134

Django Doc :

latest(field_name=None) возвращает последний объект в таблице по дате, используя field_name, указанное в качестве поля даты.

В этом примере возвращается последняя запись в таблице в соответствии с pub_dateполем:

Entry.objects.latest('pub_date')
Asinox
источник
5
Это изящный способ сделать это. Кроме того, «Если мета вашей модели указывает get_latest_by, вы можете не использовать аргумент field_name для latest ()» согласно документации.
Fredrik Möllerstrand
50

Самый простой способ сделать это:

books.objects.all().last()

Вы также можете использовать это, чтобы получить первую запись следующим образом:

books.objects.all().first()
haky_nash
источник
16
books.objects.last() и books.objects.first()должен сделать свое дело.
Чандан
Это должен быть принятый ответ вместе с XYZ.objects.first()and XYZ.objects.last()
slajma
Я думаю, что путь Арно П. является более подходящим. Это, если не ошибаюсь, распакует все элементы в БД, откуда последний извлекает последний, используя запрос БД.
Ларчо
33

Django> = 1.6

Добавлены методы QuerySet first () и last (), которые являются вспомогательными методами, возвращающими первый или последний объект, соответствующий фильтрам. Возвращает None, если совпадающие объекты отсутствуют.

панчикор
источник
32

Чтобы получить первый объект:

ModelName.objects.first()

Чтобы получить последние предметы:

ModelName.objects.last()

Вы можете использовать фильтр

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

У меня это работает.

Рави Кумар
источник
6

Когда набор запросов уже исчерпан, вы можете сделать это, чтобы избежать еще одной подсказки db -

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

Не используйте try...except....
Django IndexErrorв этом случае не бросает .
Он выдает AssertionErrorили ProgrammingError(при запуске python с параметром -O)

jifeng.yin
источник
1
Предполагая, что ваш запрос уже упорядочен, это должен быть «главный ответ», потому что это единственное решение, которое больше не попадает в базу данных.
Дэвид Д.
4

Если вы используете django 1.6 и выше, теперь это намного проще, поскольку был представлен новый api -

Model.object.earliest()

Он даст latest () с обратным направлением.

ps - Я знаю его старый вопрос, я публикую, как если бы кто-то столкнулся с этим вопросом, они узнали эту новую функцию и не использовали старый метод.

Мутант
источник
3
из документов: Early () и latest () требуют либо параметра field_name, либо get_latest_by в модели
panchicore
1

Вы можете использовать Model.objects.last()или Model.objects.first(). Если не orderingопределено, то набор запросов упорядочивается на основе первичного ключа. Если вам нужен набор запросов для упорядочивания поведения, вы можете обратиться к последним двум пунктам.

Если вы думаете сделать это, Model.objects.all().last()получить последний и Model.objects.all().first()получить первый элемент в наборе запросов или использовать filtersбез раздумий. Тогда ознакомьтесь с некоторыми предостережениями ниже.

Здесь важно отметить, что если вы не включили ничего orderingв свою модель, данные могут быть в любом порядке, и у вас будет случайный последний или первый элемент, чего не ожидалось.

Например. Допустим, у вас есть модель Model1с 2 столбцами idи item_count10 строками с идентификаторами от 1 до 10. [Порядок не определен]

Если вы получите Model.objects.all (). Last () таким образом, вы можете получить любой элемент из списка из 10 элементов. Да, это случайно, так как нет порядка по умолчанию.

Так что же можно сделать?

  1. Вы можете определить orderingна основе любого поля или полей вашей модели. У него также есть проблемы с производительностью, пожалуйста, проверьте это тоже. Ссылка: Здесь
  2. ИЛИ вы можете использовать order_byпри загрузке. Как это:Model.objects.order_by('item_count').last()
Рошан Даванде
источник
-5

Самый простой способ, не беспокоясь о текущем порядке, - это преобразовать QuerySet в список, чтобы вы могли использовать обычную отрицательную индексацию Python. Вот так:

list(User.objects.all())[-1]
Джош Урисман
источник
2
Это запросит ВСЕ объекты из БД, а затем возьмет первый
warvariuc
Хорошая точка зрения! Очевидно, не продумал это до конца. Ответ .reverse () (выбран в данный момент) - правильный путь!
Джош Урисман