Django 28. Добавляем пагинацию на сайт
В этом посте добавим пагинацию на сайт.
Дополнительные материалы
Для скачивания материалов необходимо войти или зарегистрироваться
Файлы также можно получить в Telegram-боте по коду: 519494
Реклама
Пагинация - это способ разделения больших объёмов данных на отдельные страницы, например, вывод списка пользователей, товаров или записей блога.
Пагинация позволяет ускорить загрузку страниц за счёт сегментирования содержимого, а также улучшить взаимодействие пользователя с сайтом.
Добавление функционала достаточно простое, но оно отличается в зависимости от способа написания представлений.
Разберём оба варианта.
Изменение представлений.
Пагинация в CBV.
В прошлом посте я писал о преимуществах классовых представлений от функциональных. И если в моём случае, в коде преимущество не видно сразу, то с пагинацией наоборот.
Для добавления пагинации в данные страницы достаточно добавить в код представления буквально одно поле - paginate_by
с указанием количества элементов на страницу.
На примере класса страницы тегов:
class TagPageView(ListView):
model = models.PostModel
template_name = 'blog/tag_page.html'
context_object_name = 'posts'
paginate_by = 10
# методы класса
Пагинация в FBV.
В функциональных представлениях пагинация добавляется немного другим способом.
В функции представления необходимо добавить три переменные.
paginator
- ей присваиваем объект классаPaginator
, передавая в него переменную со списком постов и количество элементов на страницу.page_number
- в неё получаем значение текущей страницы, если его нет, то по умолчанию устанавливаем 1 страницу.posts
- переменная, в которую получаем список постов для конкретной страницы
На примере функции страницы тегов:
from django.core.paginator import Paginator
def tag_page(request, tag_name):
posts_list = models.PostModel.objects.filter(tags__slug=tag_name).distinct()
paginator = Paginator(posts_list, 10)
page_number = request.GET.get('page', 1)
posts = paginator.page(page_number)
context = {
'tag_name': tag_name,
'posts': posts,
}
return render(request,
'blog/tag_page.html',
context)
Добавляем в шаблон.
После передачи данных в шаблон их нужно обработать.
Для оформления вывода будем использовать стили пагинатора из Bootstrap.
Перейдём в директорию шаблонов и создадим файл pagination.html
. Для удобства можно создать директорию modules
и поместить его туда.
В файле напишем три блока:
- Первый отвечает за кнопку назад, функционал и отображение.
- Второй за кнопки страниц.
- Третий за кнопку вперёд.
Код.
<nav aria-label="Page navigation">
<ul class="pagination justify-content-center">
{% if page_obj.has_previous %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.previous_page_number }}">Назад</a></li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Назад</span>
</li> {% endif %}
{% for num_page in page_obj.paginator.page_range %}
{% if num_page page_obj.number %}
<li class="page-item active"><a class="page-link" href="#">{{ num_page }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="?page={{ num_page }}">{{ num_page }}</a></li>
{% endif %}
{% endfor %}
{% if page_obj.has_next %}
<li class="page-item"><a class="page-link" href="?page={{ page_obj.next_page_number }}">Вперед</a></li>
{% else %}
<li class="page-item disabled">
<span class="page-link">Вперед</span>
</li> {% endif %}
</ul>
</nav>
В данном файле мы получаем все данные из переменной page_obj
. Это переменная, представляющая собой объект страницы.
Подключаем на странице.
Теперь этот файл необходимо подключить в шаблоне страницы, продолжим пример на странице тегов.
Откроем файл tag_page.html
.
До закрытия тега div
с классом container
добавляем следующий блок:
Для CBV:
<div class="col-12">
{% include "blog/modules/pagination.html" %}
</div>
Для FBV:
<div class="col-12">
{% include "blog/modules/pagination.html" with page_obj=posts %}
</div>
Обратите внимание. Во втором случае, мы передаём в шаблон переменную posts под видом переменной page_obj. Этого можно и не делать, заменив в файле pagination.html все page_obj на posts
Теперь можно запустить Django и убедиться, что пагинация работает.
Все статьи