Добавляя контент на блог, вы быстро придете к выводу, что список постов лучше делить на несколько страниц. В Django есть встроенный класс пагинации, который позволяет сделать это очень быстро.
Отредактируйте файл views.py
приложения blog
, чтобы импортировать класс Paginator
и измените представление post_list
следующим образом:
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def post_list(request):
object_list = Post.published.all()
paginator = Paginator(object_list, 3) # 3 поста на каждой странице
page = request.GET.get('page')
try:
posts = paginator.page(page)
except PageNotAnInteger:
# Если страница не является целым числом, поставим первую страницу
posts = paginator.page(1)
except EmptyPage:
# Если страница больше максимальной, доставить последнюю страницу результатов
posts = paginator.page(paginator.num_pages)
return render(request,
'blog/post/list.html',
{'page': page,
'posts': posts})
Вот как работает этот класс:
- Создается экземпляр класса
Paginator
с количеством объектов, которые нужно отображать на одной странице. - Получаем параметр
page GET
, который указывает на текущую страницу. - Получаем объекты для нужной страницы, вызывая метод page() метода
Paginator
. - Если параметр
page
— это не целое число, возвращаем первую страницу результатов. Если оно больше последней страницы результатов, возвращаем последнюю. - Передаем шаблону номер страницы и полученные объекты.
Теперь нужно создать шаблон для отображения пагинатора так, чтобы он мог использоваться в любом шаблоне с пагинацией. В папке templates/
приложения blog
создайте новый файл и назовите его pagination.html
. Добавьте туда следующий код:
<div class="pagination">
<span class="step-links">
{% if page.has_previous %}
<a href="?page={{ page.previous_page_number }}">Previous</a>
{% endif %}
<span class="current">
Page {{ page.number }} of {{ page.paginator.num_pages }}.
</span>
{% if page.has_next %}
<a href="?page={{ page.next_page_number }}">Next</a>
{% endif %}
</span>
</div>
Шаблон пагинации ожидает получить объект Page
, чтобы отрисовать ссылки «Previous» и «Next», а также для отображения текущей страницы и общее количество страниц результата. Вернемся к шаблону blog/post/list.html
и добавим шаблон pagination.html
в нижней части блока {% content %}
:
{% block content %}
...
{% include "../pagination.html" with page=posts %}
{% endblock %}
Поскольку объект Page
, который передается шаблону, называется posts
, передадим шаблон пагинации в шаблон списка постов вместе с параметрами для корректного рендеринга. Этот способ можно применять, чтобы использовать шаблон пагинации в постраничных представлениях разных моделей.
Теперь откройте https://127.0.0.1:8000/blog/
в браузере. Вы увидите элементы навигации по страницам в нижней части и сможете перемещаться по ним.