Spec-Zone.ru › Django 2.1

Пагинация

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]
Новое в Django 2.0.

Возвращает объект 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]

Возвращает индекс первой записи на странице (с индексацией с 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/2.1/topics/pagination/

Spec-Zone.ru

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