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

Как я могу получить последнюю запись в определенном наборе запросов?


person Stephen    schedule 03.02.2010    source источник


Ответы (9)


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


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

queryset.reverse()[0]

Кроме того, остерегайтесь этого предупреждения из документации Django:

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

person jujule    schedule 03.02.2010
comment
как сказано в документах django: обратите внимание, что reverse() обычно следует вызывать только для QuerySet, который имеет определенный порядок (например, при запросе к модели, которая определяет порядок по умолчанию, или при использовании order_by()). Если такой порядок не определен для данного QuerySet, вызов reverse() для него не имеет реального эффекта (порядок был неопределенным до вызова reverse() и останется неопределенным впоследствии). - person jujule; 03.02.2010
comment
2017, и принятые ответы устарели. Как показано ниже, вы должны использовать queryset.last(). - person wobbily_col; 14.07.2017

Django Doc:

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

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

Entry.objects.latest('pub_date')
person Asinox    schedule 23.08.2010
comment
Это аккуратный способ сделать это. Кроме того, если метаданные вашей модели указывают get_latest_by, вы можете не использовать аргумент field_name для last() в соответствии с документами. - person Fredrik Möllerstrand; 05.03.2013

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

books.objects.all().last()

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

books.objects.all().first()
person haky_nash    schedule 13.11.2015
comment
books.objects.last() и books.objects.first() должны помочь. - person chandan; 08.05.2016
comment
Это должен быть принятый ответ вместе с XYZ.objects.first() и XYZ.objects.last() - person slajma; 25.09.2018
comment
Я думаю, что путь Арно П. является более подходящим. Это, если не ошибаюсь, распаковывает все элементы в БД, где более поздний извлекает последний, используя запрос БД. - person Larcho; 29.05.2020

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

ModelName.objects.first()

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

ModelName.objects.last()

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

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

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

person Ravi Kumar    schedule 25.11.2015

Джанго >= 1,6

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

person panchicore    schedule 21.01.2014

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

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

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

person jifeng.yin    schedule 14.05.2014
comment
Предполагая, что ваш набор запросов уже упорядочен, это должен быть лучший ответ, потому что это единственное решение, которое больше не попадает в базу данных. - person David D.; 26.07.2018

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

Model.object.earliest()

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

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

person Mutant    schedule 11.01.2014
comment
из документов: Early() и last() требуют либо параметра field_name, либо 'get_latest_by' в модели - person panchicore; 21.01.2014

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

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

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

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

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

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

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

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

list(User.objects.all())[-1]
person Josh Ourisman    schedule 07.02.2013
comment
Это запросит ВСЕ объекты из БД, а затем возьмет первый - person warvariuc; 01.03.2013
comment
Хорошая точка зрения! Явно не подумал об этом. Ответ .reverse() (в настоящее время выбран) - правильный путь! - person Josh Ourisman; 29.03.2013