Блог на Django #17: Добавление пагинации

2060

Добавляя контент на блог, вы быстро придете к выводу, что список постов лучше делить на несколько страниц. В 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})

Вот как работает этот класс:

  1. Создается экземпляр класса Paginator с количеством объектов, которые нужно отображать на одной странице.
  2. Получаем параметр page GET, который указывает на текущую страницу.
  3. Получаем объекты для нужной страницы, вызывая метод page() метода Paginator.
  4. Если параметр page — это не целое число, возвращаем первую страницу результатов. Если оно больше последней страницы результатов, возвращаем последнюю.
  5. Передаем шаблону номер страницы и полученные объекты.

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

Элементы навигации по страницам django

Учитесь программировать по книгам, подписывайте на телеграм каналы:

Книги Python разработчика RU / EN

Книги / Data Science / RU-EN

Тест на знание python

Что выведет этот код?
Какая из следующих функций проверяет, что все символы строки в верхнем регистре?
Какой будет результат выполнения этого кода?
Какой будет результат выполнения кода в python 3 — print(3/5) ?
Как узнать длину списка?
Александр
Я создал этот блог в 2018 году, чтобы распространять полезные учебные материалы, документации и уроки на русском. На сайте опубликовано множество статей по основам python и библиотекам, уроков для начинающих и примеров написания программ. Пишу на популярные темы: веб-разработка, работа с базами данных, data sciense и другие...