Spec-Zone.ru › Django 2.0

Разбиение на страницы

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 EmptyPage, PageNotAnInteger, 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 в модели.

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

Если вы используете набор данных с очень большим количеством элементов, запрос высоких номеров страниц может быть медленным на некоторых базах данных, потому что для подсчета количества записей OFFSET в результирующем запросе LIMIT/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]

Возвращает индекс первой записи на странице (с единицы), относительно всего списка объектов в пагинаторе. Например, при пагинации списка из 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.0/topics/pagination/

Spec-Zone.ru

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