Spec-Zone.ru › Django 2.2

Пагинация

Django предоставляет несколько классов, которые помогают управлять данными, разбитыми на страницы – с ссылками «Предыдущая/Следующая». Эти классы находятся в django/core/paginator.py.

Пример

Передайте Paginator список объектов и количество элементов на каждой странице, и он предоставит методы для доступа к элементам каждой страницы:

>>> from django.core.paginator import Paginator
>>> objects = ['john', 'paul', 'george', 'ringo']
>>> p = Paginator(objects, 2)

>>> p.count
4
>>> p.num_pages
2
>>> type(p.page_range)
<class 'range_iterator'>
>>> p.page_range
range(1, 3)

>>> page1 = p.page(1)
>>> page1
<Page 1 of 2>
>>> page1.object_list
['john', 'paul']

>>> page2 = p.page(2)
>>> page2.object_list
['george', 'ringo']
>>> page2.has_next()
False
>>> page2.has_previous()
True
>>> page2.has_other_pages()
True
>>> page2.next_page_number()
Traceback (most recent call last):
...
EmptyPage: That page contains no results
>>> page2.previous_page_number()
1
>>> page2.start_index() # The 1-based index of the first item on this page
3
>>> page2.end_index() # The 1-based index of the last item on this page
4

>>> p.page(0)
Traceback (most recent call last):
...
EmptyPage: That page number is less than 1
>>> p.page(3)
Traceback (most recent call last):
...
EmptyPage: That page contains no results

Примечание

Обратите внимание, что вы можете передать Paginator список/кортеж, Django QuerySet, или любой другой объект с методом count() или __len__(). При определении количества объектов в переданном объекте, Paginator сначала попробует вызвать count(), а затем использует len(), если у переданного объекта нет метода count(). Это позволяет объектам, таким как Django QuerySet, использовать более эффективный метод count() при его наличии.

Использование Paginator в представлении

Вот немного более сложный пример использования Paginator в представлении для пагинации набора результатов запроса. Мы предоставляем как представление, так и соответствующий шаблон, чтобы показать, как отображать результаты. В этом примере предполагается, что у вас есть модель Contacts, которая уже импортирована.

Функция представления выглядит так:

from django.core.paginator import Paginator
from django.shortcuts import render

def listing(request):
    contact_list = Contacts.objects.all()
    paginator = Paginator(contact_list, 25) # Show 25 contacts per page

    page = request.GET.get('page')
    contacts = paginator.get_page(page)
    return render(request, 'list.html', {'contacts': contacts})

В шаблоне list.html, вы захотите включить навигацию между страницами, а также любую интересную информацию из самих объектов:

{% for contact in contacts %}
    {# Each "contact" is a Contact model object. #}
    {{ contact.full_name|upper }}<br>
    ...
{% endfor %}

<div class="pagination">
    <span class="step-links">
        {% if contacts.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ contacts.previous_page_number }}">previous</a>
        {% endif %}

        <span class="current">
            Page {{ contacts.number }} of {{ contacts.paginator.num_pages }}.
        </span>

        {% if contacts.has_next %}
            <a href="?page={{ contacts.next_page_number }}">next</a>
            <a href="?page={{ contacts.paginator.num_pages }}">last &raquo;</a>
        {% endif %}
    </span>
</div>

Paginator объекты

Класс Paginator имеет такой конструктор:

class Paginator(object_list, per_page, orphans=0, allow_empty_first_page=True) [source]

Обязательные аргументы

object_list

Список, кортеж, QuerySet, или другой срезовываемый объект с методом count() или __len__(). Для согласованной пагинации объекты должны быть упорядочены, например, с помощью order_by() или с помощью полей ordering в модели.

Проблемы производительности при пагинации больших QuerySet

Если вы используете QuerySet с очень большим количеством элементов, запросы к высоким страницам могут быть медленными на некоторых базах данных, потому что результирующий LIMIT/OFFSET запрос должен подсчитать количество OFFSET записей, что занимает больше времени по мере увеличения номера страницы.

per_page
Максимальное количество элементов на странице, не включая "осиротевшие" (см. необязательный аргумент orphans ниже).

Необязательные аргументы

orphans
Используйте этот параметр, когда не хотите, чтобы последняя страница содержала очень мало элементов. Если последняя страница обычно содержит количество элементов меньше или равно orphans, то эти элементы будут добавлены к предыдущей странице (которая становится последней), вместо того, чтобы оставлять их на отдельной странице. Например, с 23 элементами, per_page=10, и orphans=3, будет две страницы; первая с 10 элементами, а вторая (и последняя) с 13 элементами. По умолчанию orphans равен нулю, что означает, что страницы никогда не объединяются, а последняя страница может содержать один элемент.
allow_empty_first_page
Разрешено ли пустая первая страница. Если False и object_list пусто, то будет поднято исключение EmptyPage.

Методы

Paginator.get_page(number) [source]

Возвращает объект Page с заданным индексом (с учётом нумерации с 1), а также обрабатывает номера страниц вне диапазона и некорректные значения.

Если страница не является числом, возвращается первая страница. Если номер страницы отрицательный или больше, чем количество страниц, возвращается последняя страница.

Исключение (EmptyPage) поднимается только если вы указали Paginator(..., allow_empty_first_page=False) и object_list пусто.

Paginator.page(number) [source]

Возвращает объект Page с заданным индексом (с учётом нумерации с 1). Поднимает исключение InvalidPage, если заданного номера страницы не существует.

Атрибуты

Paginator.count

Общее количество объектов на всех страницах.

Примечание

При определении количества объектов в object_list, Paginator сначала попробует вызвать object_list.count(). Если object_list не имеет метода count(), то Paginator перейдёт к использованию len(object_list). Это позволяет объектам, таким как Django QuerySet, использовать более эффективный метод count() при его наличии.

Paginator.num_pages

Общее количество страниц.

Paginator.page_range

Итератор диапазона номеров страниц (с нумерацией с 1), например, возвращая [1, 2, 3, 4].

InvalidPage исключения

exception InvalidPage [source]

Базовый класс исключений, поднимаемых, когда пагинатор получает неверный номер страницы.

Метод Paginator.page() поднимает исключение, если запрошенная страница неверна (то есть не является целым числом) или не содержит объектов. Обычно достаточно перехватить исключение InvalidPage, но если вам нужна более подробная информация, вы можете перехватить одно из следующих исключений:

exception PageNotAnInteger [source]

Поднимается, если page() получает значение, которое не является целым числом.

exception EmptyPage [source]

Поднимается, если page() получает действительное значение, но объектов на этой странице нет.

Оба исключения являются подклассами InvalidPage, поэтому вы можете обработать их оба с помощью простого блока except InvalidPage.

Page объекты

Обычно вы не будете создавать объекты Page вручную – вы получите их с помощью Paginator.page().

class Page(object_list, number, paginator) [source]

Страница ведет себя как последовательность Page.object_list при использовании len() или итерации напрямую.

Методы

Page.has_next() [source]

Возвращает True если следующая страница существует.

Page.has_previous() [source]

Возвращает True если предыдущая страница существует.

Page.has_other_pages() [source]

Возвращает True если следующая или предыдущая страница существует.

Page.next_page_number() [source]

Возвращает номер следующей страницы. Вызывает InvalidPage, если следующей страницы не существует.

Page.previous_page_number() [source]

Возвращает номер предыдущей страницы. Вызывает InvalidPage, если предыдущей страницы не существует.

Page.start_index() [source]

Возвращает индекс первой записи на странице, отсчитываемый от начала всего списка объектов в пагинаторе. Например, при разбиении списка из 5 объектов на страницы по 2 объекта на страницу, индекс start_index() второй страницы будет 3.

Page.end_index() [source]

Возвращает индекс последней записи на странице, отсчитываемый от начала всего списка объектов в пагинаторе. Например, при разбиении списка из 5 объектов на страницы по 2 объекта на страницу, индекс end_index() второй страницы будет 4.

Атрибуты

Page.object_list

Список объектов на этой странице.

Page.number

Номер страницы (с единицы) для этой страницы.

Page.paginator

Соответствующий объект Paginator.

© Django Software Foundation and individual contributors
Licensed under the BSD License.
https://docs.djangoproject.com/en/2.2/topics/pagination/

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API