Link Search Menu Expand Document

Постраничная навигация

Подробнее про пагинацию

Пример использования

Для начала импортируем класс пагинации:

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)
Метод классаОписание
p.countКоличество элементов для пагинации
p.num_pagesКоличество страниц пагинации
p.page_rangeВозвращает итератор страниц пагинации
p.page(1)Возвращает объект с записями для первой страницы
p.page(1).object_listПолучим первые записи для первой страницы пагинации

Подробный пример рассмотрен тут

Применем пагинацию к нашему проекту

Если мы используем объекты-функции:

Руководство по пагинации с использованием объектов-функций

Создадим в файле views.py объекты-функцию для демонстрации:

def test(request):
    objects = ['john1', 'paul2', 'george3', 'ringo4', 'john5', 'paul6', 'george7']
    paginator = Paginator(objects, 2)
    page_num = request.GET.get('page', 1)  
    # Вторым параметром мы указываем число которое будет подставленно в случае если метод GET ничего не получит
    page_objects = paginator.get_page(page_num)
    return render(request, 'news/test.html', {'page_obj': page_objects})

Далее пропишем в файле urls.py путь: path('test/',test, name='test'),

И создадим шаблон news/test.html:

{% extends 'base.html' %}
{% block title %}
Тестовая страница
{% endblock %}
{% block sidebar %}
{% include 'inc/_sidebar.html'%}
{% endblock %}
{% block content %}
{% for name in page_obj.object_list %}
<p>{{ name }}</p>
{% endfor %}
{% endblock %}

Дале в наш базовый шаблон base.html вставим блок пагинации:

<div class="col-md-9">
    {% block content %}CONTENT{% endblock %}
    <nav aria-label="...">
        <ul class="pagination">
            {% if page_obj.has_previous %}
            <li class="page-item">
                <a class="page-link" href="?page={{ page_obj.previous_page_number }}" tabindex="-1">Previous</a>
            </li>
            {% endif %}
            {% for p in page_obj.paginator.page_range%}
            {% if page_obj.number == p %}
            <li class="page-item active" aria-current="page">
                <a class="page-link" href="#">{{ p }} <span class="sr-only">(current)</span></a>
            </li>
            {% elif p > page_obj.number|add:-3 and p < page_obj.number|add:3 %}
            <li class="page-item">
                <a class="page-link" href="?page={{ p }}">{{ p }}</a>
            </li>
            {% endif %}
            {% endfor %}
            {% if page_obj.has_next %}
            <li class="page-item">
                <a class="page-link" href="?page={{ page_obj.next_page_number }}">Next</a>
            </li>
            {% endif %}
        </ul>
    </nav>
</div>

Таким образом {% elif p > page_obj.number|add:-3 and p < page_obj.number|add:3 %} мы выводим по 2 страницы слева и справа от текущей.

Если мы используем объекты-классы:

В классе наследник ListView нужно добавить свойство paginate_by = 2, все остальное сделает класс ListView. После этого в шаблоне станут доступны объекты класса paginator.