Постраничная навигация
Пример использования
Для начала импортируем класс пагинации:
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
.