Spec-Zone.ru › Django 1.9

Пагинация

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)  # `<type 'rangeiterator'>` in Python 2.
<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, EmptyPage, PageNotAnInteger
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')
    try:
        contacts = paginator.page(page)
    except PageNotAnInteger:
        # If page is not an integer, deliver first page.
        contacts = paginator.page(1)
    except EmptyPage:
        # If page is out of range (e.g. 9999), deliver last page of results.
        contacts = paginator.page(paginator.num_pages)

    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={{ 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>
        {% endif %}
    </span>
</div>

Paginator объекты

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

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

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

object_list

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

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

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

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

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

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

Методы

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].

В более старых версиях page_range возвращал список вместо итератора.

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]

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

Page.end_index() [source]

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

Атрибуты

Page.object_list

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

Page.number

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

Page.paginator

Связанный объект Paginator.

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

Spec-Zone.ru

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