Пагинатор¶
Django предоставляет несколько классов, которые помогут вам управлять данными, разбитыми на страницы, то есть данными, разделенными на несколько страниц со ссылками «Предыдущий/Следующий». Эти классы находятся в django/core/paginator.py.
Примеры см. в Справочнике по разбивке на страницы.
Класс Пагинатор¶
- class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True, error_messages=None)¶
Пагинатор действует как последовательность
Pageпри использованииlen()или его прямой итерации.
- Paginator.object_list¶
Необходимый. Список, кортеж, QuerySet или другой срезаемый объект с помощью метода count() или __len__(). Для последовательной нумерации страниц следует упорядочить
QuerySet, например: с предложениемorder_by()или со значением по умолчаниюorderingдля модели.Проблемы с производительностью при разбиении на страницы больших
QuerySetов.Если вы используете
QuerySetс очень большим количеством элементов, запрос больших номеров страниц может быть медленным в некоторых базах данных, поскольку результирующий запросLIMIT/OFFSETдолжен подсчитывать количество записейOFFSET, что занимает больше времени по мере увеличения номера страницы.
- Paginator.per_page¶
Необходимый. Максимальное количество элементов, которые можно включить на страницу, не включая потерянные элементы (см. необязательный аргумент
orphansниже).
- Paginator.orphans¶
Необязательный. Используйте это, если вы не хотите, чтобы на последней странице было очень мало элементов. Если на последней странице обычно количество элементов меньше или равно «сиротам», то эти элементы будут добавлены на предыдущую страницу (которая станет последней страницей), а не оставлять элементы на странице сами по себе. Например, при 23 элементах per_page=10 и orphans=3 будет две страницы; первая страница с 10 элементами и вторая (и последняя) страница с 13 элементами. По умолчанию «сироты» равны нулю, что означает, что страницы никогда не объединяются, и последняя страница может содержать один элемент.
orphansдолжно быть меньше значенияper_page.Не рекомендуется, начиная с версии 6.0: Поддержка аргумента
orphans, превышающего или равного аргументуper_page, устарела.
- Paginator.allow_empty_first_page¶
Необязательный. Разрешается ли первой странице быть пустой. Если
Falseиobject_listпусты, то будет выдана ошибкаEmptyPage.
- Paginator.error_messages¶
Аргумент error_messages позволяет вам переопределить сообщения по умолчанию, которые будет выдавать пагинатор. Передайте словарь с ключами, соответствующими сообщениям об ошибках, которые вы хотите переопределить. Доступные ключи сообщений об ошибках:
invalid_page,min_pageиno_results.Например, вот сообщение об ошибке по умолчанию:
>>> from django.core.paginator import Paginator >>> paginator = Paginator([1, 2, 3], 2) >>> paginator.page(5) Traceback (most recent call last): ... EmptyPage: That page contains no results
А вот специальное сообщение об ошибке:
>>> paginator = Paginator( ... [1, 2, 3], ... 2, ... error_messages={"no_results": "Page does not exist"}, ... ) >>> paginator.page(5) Traceback (most recent call last): ... EmptyPage: Page does not exist
Методы¶
- Paginator.get_page(number)¶
Возвращает объект
Pageс заданным индексом, отсчитываемым от 1, а также обрабатывает выходящие за пределы диапазона и недопустимые номера страниц.Если страница не является числом, возвращается первая страница. Если номер страницы отрицательный или превышает количество страниц, возвращается последняя страница.
Вызывает исключение
EmptyPage, только если вы указываетеPaginator(...,allow_empty_first_page=False)иobject_listпуст.
- Paginator.page(number)¶
Возвращает объект
Pageс заданным индексом, отсчитываемым от 1. ВызываетPageNotAnInteger, есличислоне может быть преобразовано в целое число с помощью вызоваint(). ВызываетEmptyPage, если указанный номер страницы не существует.
- Paginator.get_elided_page_range(number, *, on_each_side=3, on_ends=2)¶
Возвращает список номеров страниц, отсчитываемый от 1, аналогичный
Paginator.page_range, но может добавлять многоточие к одной или обеим сторонам текущего номера страницы, еслиPaginator.num_pagesбольшой.Количество страниц, включаемых с каждой стороны текущего номера страницы, определяется аргументом on_each_side, который по умолчанию равен 3.
Количество страниц, включаемых в начало и конец диапазона страниц, определяется аргументом on_ends, который по умолчанию равен 2.
Например, при значениях по умолчанию для
on_each_sideиon_ends, если текущая страница равна 10 и имеется 50 страниц, диапазон страниц будет[1, 2, '…', 7, 8, 9, 10, 11, 12, 13, '…', 49, 50]. В результате страницы 7, 8 и 9 появятся слева от текущей страницы, а страницы 11, 12 и 13 — справа от текущей, а также страницы 1 и 2 в начале и 49 и 50 в конце.Вызывает
InvalidPage, если указанный номер страницы не существует.
Атрибуты¶
- Paginator.ELLIPSIS¶
Переводимая строка, используемая вместо пропущенных номеров страниц в диапазоне страниц, возвращаемом
get_elided_page_range(). По умолчанию'…'.
- Paginator.count¶
Общее количество объектов на всех страницах.
Примечание
При определении количества объектов, содержащихся в
object_list,Paginatorсначала попытается вызватьobject_list.count(). Еслиobject_listне имеет методаcount(), тогдаPaginatorвернется к использованиюlen(object_list). Это позволяет объектам, таким как QuerySet, использовать более эффективный метод count(), если он доступен.
- Paginator.num_pages¶
Общее количество страниц.
- Paginator.page_range¶
Итератор диапазона номеров страниц, отсчитываемый от 1, например. давая
[1, 2, 3, 4].
Класс AsyncPaginator¶
- class AsyncPaginator(object_list, per_page, orphans=0, allow_empty_first_page=True, error_messages=None)¶
Асинхронная версия
Paginator.AsyncPaginatorимеет те же атрибуты и подписи, что иPaginator, за следующими исключениями:Атрибут
Paginator.countподдерживается как асинхронный методAsyncPaginator.acount().Атрибут
Paginator.num_pagesподдерживается как асинхронный методAsyncPaginator.anum_pages().Атрибут
Paginator.page_rangeподдерживается как асинхронный методAsyncPaginator.apage_range().
AsyncPaginatorимеет асинхронные версии тех же методов, что иPaginator, с использованием префиксаa- например, используйтеawait async_paginator.aget_page(number)вместоpaginator.get_page(number).
Класс Страница¶
Обычно вы не будете создавать объекты Page вручную — вы получите их путем итерации Paginator или с помощью Paginator.page().
- class Page(object_list, number, paginator)¶
Страница действует как последовательность
Page.object_listпри использованииlen()или ее прямой итерации.
Методы¶
- Page.has_next()¶
Возвращает True, если есть следующая страница.
- Page.has_previous()¶
Возвращает
True, если есть предыдущая страница.
- Page.has_other_pages()¶
Возвращает
True, если есть следующая или предыдущая страница.
- Page.next_page_number()¶
Возвращает номер следующей страницы. Вызывает
InvalidPage, если следующая страница не существует.
- Page.previous_page_number()¶
Возвращает номер предыдущей страницы. Вызывает
InvalidPage, если предыдущая страница не существует.
- Page.start_index()¶
Возвращает индекс первого объекта на странице, отсчитываемый от 1, относительно всех объектов в списке пагинатора. Например, при разбиении на страницы списка из 5 объектов по 2 объекта на странице,
start_index()второй страницы вернет3.
- Page.end_index()¶
Возвращает индекс последнего объекта на странице, отсчитываемый от 1, относительно всех объектов в списке пагинатора. Например, при разбиении на страницы списка из 5 объектов по 2 объекта на странице,
end_index()второй страницы вернет4.
Атрибуты¶
- Page.object_list¶
Список объектов на этой странице.
- Page.number¶
Номер страницы, отсчитываемый от 1.
Класс AsyncPage¶
- class AsyncPage(object_list, number, paginator)¶
Асинхронная версия
Page.AsyncPageимеет те же атрибуты и подписи, что иPage, а также асинхронные версии всех тех же методов с использованием префиксаa- например, используйтеawait async_page.ahas_next()вместоpage.has_next().AsyncPageимеет следующий дополнительный метод:- aget_object_list()¶
Возвращает AsyncPage.object_list в виде списка. Этот метод необходимо дождаться, прежде чем
AsyncPageможно будет рассматривать как последовательностьAsyncPage.object_list.
Исключения¶
- exception InvalidPage¶
Базовый класс для исключений, возникающих, когда средству разбиения на страницы передается недопустимый номер страницы.
Метод Paginator.page() вызывает исключение, если запрошенная страница недействительна (т. е. не является целым числом) или не содержит объектов. Как правило, достаточно перехватить исключение InvalidPage, но если вам нужна большая детализация, вы можете перехватить любое из следующих исключений:
- exception PageNotAnInteger¶
Возникает, когда
page()присваивается значение, не являющееся целым числом.
- exception EmptyPage¶
Возникает, когда
page()присвоено допустимое значение, но на этой странице не существует объектов.
Оба исключения являются подклассами InvalidPage, поэтому вы можете обрабатывать их оба с помощью кроме InvalidPage.