Limit и Offset в Django QuerySet

В этом уроке вы узнаете, как ограничить QuerySet в Django, что эквивалентно предложениям LIMIT и OFFSET в SQL.

На практике вы редко получаете все строки из одной или нескольких таблиц в базе данных. Вместо этого используется подмножество строк для отображения на веб-странице.

Django использует синтаксис срезов, чтобы ограничить QuerySet определенным количеством объектов. За кулисами Django выполняет оператор SQL SELECT с предложениями LIMIT и OFFSET.

Предположим, вы хотите получить доступ к первым 10 строкам таблицы. Для этого можно использовать следующий срез:

Entity.objects.all()[:10]

Поскольку таблица хранит строки в неопределенном порядке, «первые 10 объектов» становятся непредсказуемыми.

Поэтому всегда следует сортировать результаты перед тем, как применить слайсинг к запросу. Например, следующий код получает первые 10 строк, упорядоченных по field_name:

Entity.objects.all().order_by(field_name)[:10]

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

Entity.objects.all().order_by(field_name)[10:20]

В общем случае синтаксис ограничения результатов выглядит следующим образом:

Entity.objects.all()[Offset:Offset+Limit]

В этом синтаксисе Offset — это количество строк, которые вы хотите пропустить, а Limit — это количество строк, которые вы хотите извлечь.

Обратите внимание, что Django не поддерживает отрицательную индексацию, например:

Entity.objects.all().order_by(field_name)[-10]

Кроме того, при слайсинге QuerySet Django возвращает новый QuerySet.

Чтобы получить первую или последнюю строку, следует использовать метод first() или last(), поскольку если QuerySet пуст и вы используете срез:

Entity.objects.all().order_by(field_name)[0]

…то вы получите исключение IndexError.

Пример Limit Offset в Django

Для демонстрации мы будем использовать модель Employee из приложения HR. Модель Employee сопоставляется с таблицей hr_employee:

Пример с Limit Offset

В следующем примере первые 10 сотрудников сортируются по именам:

>>> Employee.objects.all().order_by('first_name')[:10] 
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY "hr_employee"."first_name" ASC
 LIMIT 10
Execution time: 0.000000s [Database: default]
<QuerySet [<Employee: Aaron Pearson>, <Employee: Adam Crane>, <Employee: Adam Stewart>, <Employee: Adrienne Green>, <Employee: Alan Johnson>, <Employee: Alexa West>, <Employee: Alicia Wyatt>, <Employee: Amanda Benson>, <Employee: Amber Brown>, <Employee: Amy Lopez>]>

В следующем примере первые 10 строк пропускаются, а следующие 10 строк извлекаются из таблицы hr_employee:

>>> Employee.objects.order_by('first_name')[10:20] 
SELECT "hr_employee"."id",
       "hr_employee"."first_name",
       "hr_employee"."last_name",
       "hr_employee"."contact_id",
       "hr_employee"."department_id"
  FROM "hr_employee"
 ORDER BY "hr_employee"."first_name" ASC
 LIMIT 10
OFFSET 10
Execution time: 0.001001s [Database: default]
<QuerySet [<Employee: Amy Lee>, <Employee: Andre Perez>, <Employee: Andrea Mcintosh>, <Employee: Andrew Dixon>, <Employee: Andrew Guerra>, <Employee: Ann Chang>, 
<Employee: Anne Odom>, <Employee: Anthony Fuentes>, <Employee: Anthony Welch>, <Employee: Ashley Brown>]>
Похожие посты
Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *