Отримати останній запис у наборі запитів


Відповіді:


81

EDIT: Тепер ви повинні використовувати Entry.objects.latest('pub_date')


Ви можете просто зробити щось подібне, використовуючи reverse():

queryset.reverse()[0]

Також остерігайтеся цього попередження з документації Django:

... зверніть увагу, що, reverse()як правило, слід викликати лише набір QuerySet, який має визначене впорядкування (наприклад, при запиті до моделі, яка визначає порядок за замовчуванням, або при використанні order_by()). Якщо для даного замовлення не визначено такого замовлення QuerySet, заклик reverse()до нього не має реального ефекту (замовлення було невизначеним до виклику reverse()та надалі залишатиметься невизначеним).


2
як сказано в документах django,: "зауважте, що reverse (), як правило, слід викликати лише в QuerySet, який має визначене впорядкування (наприклад, при запиті до моделі, яка визначає порядок за замовчуванням, або при використанні order_by ()). Якщо ні таке впорядкування визначено для даного QuerySet, виклик reverse () на ньому не має реального ефекту (порядок був невизначений до виклику reverse (), а після цього залишиться невизначеним). "
липень

6
2017 р. Та прийняті відповіді застаріли. Як показано нижче, ви повинні використовувати queryset.last ().
wobbily_col

134

Django Doc :

latest(field_name=None) повертає останній об'єкт у таблиці за датою, використовуючи ім'я_поля, вказане як поле дати.

Цей приклад повертає останній запис у таблиці відповідно до pub_dateполя:

Entry.objects.latest('pub_date')

5
Це акуратний спосіб це зробити. Крім того, "Якщо мета вашої моделі вказує get_latest_by, ви можете залишити аргумент field_name до latest ()" відповідно до документів.
Фредрік Меллерстранд 04.03.13

50

Найпростіший спосіб це зробити:

books.objects.all().last()

Ви також використовуєте це, щоб отримати перший запис так:

books.objects.all().first()

16
books.objects.last() і books.objects.first()повинен зробити трюк.
chandan

Це повинна бути прийнята відповідь разом із XYZ.objects.first()і 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

Коли набір запитів вже вичерпаний, ви можете зробити це, щоб уникнути чергової підказки в базі даних -

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

Не використовуйте try...except....
Django не кидає IndexErrorв цьому випадку.
Викидає AssertionErrorабо ProgrammingError(коли ви запускаєте python з опцією -O)


1
Якщо припустити, що ваш набір запитів уже впорядкований, це має бути "найкращою відповіддю", оскільки це єдине рішення, яке не потрапляє в базу даних знову.
Девід Д.

4

Якщо ви використовуєте django 1.6 і новіших версій, це стало набагато простіше тепер, коли був представлений новий api -

Model.object.earliest()

Це дасть останній () із зворотним напрямком.

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


3
from docs: Earliest () і 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
Це
запитає

Гарна думка! Очевидно, не думав, що до кінця. Відповідь .reverse () (вибрана на даний момент) - це правильний шлях!
Джош Урісман,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.