JavaRush /Курсы /Модуль 3: Django /Пагинация данных

Пагинация данных

Модуль 3: Django
8 уровень , 8 лекция
Открыта

Допустим, мы находимся на той стадии, когда в базе данных нашего Django-приложения накопилось так много записей, что их невозможно "съесть" за один раз. Давайте изучим пагинацию — инструмент, который помогает разрезать данные на удобоваримые порции. Готовы? Начинаем!

Зачем нужна пагинация?

Представьте себе гипотетический интернет-магазин с миллионами товаров. Если вы вдруг решите вывести все эти товары на одну веб-страницу, то ваш сервер может попрощаться с адекватной производительностью, а ваш пользователь — со стабильным интернет-соединением. Это не описание конца света, но уже близко.

Пагинация позволяет разбить огромные массивы данных (например, записи QuerySet) на страницы фиксированного размера и предоставлять их пользователю порциями. Это полезно для отображения данных в таблицах, списках, лентах соцсетей или любых других интерфейсах, где объем информации потенциально велик.

Вот еще пара причин освоить пагинацию:

  • Пользовательский опыт: никто не хочет прокручивать бесконечную страницу.
  • Снижение нагрузки на сервер: меньше передаваемых данных.
  • Ускорение отображения данных: пользователи быстрее получают информацию (маленькими кусочками

Давайте сразу перейдем к практике. Погнали!

Реализация пагинации в Django

Django предоставляет встроенные инструменты для пагинации, которые легко интегрируются с вашими представлениями и QuerySet. Основной герой здесь — класс Paginator, о котором мы поговорим ниже.

1. Класс Paginator

Класс Paginator из модуля django.core.paginator берет QuerySet или список данных и "режет" его на страницы. Каждая страница представляет собой набор записей, с которыми можно работать.

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

Начнем с простого примера и создадим пагинатор. Допустим, мы хотим разбить список продуктов на порции по 10 штук:

from django.core.paginator import Paginator

# Список данных (например, товары в интернет-магазине)
products = ['Товар 1', 'Товар 2', 'Товар 3', 'Товар 4', 'Товар 5',
            'Товар 6', 'Товар 7', 'Товар 8', 'Товар 9', 'Товар 10',
            'Товар 11', 'Товар 12']

# Создаем пагинатор с размером страницы = 5
paginator = Paginator(products, 5)

# Доступ к страницам
page_1 = paginator.page(1)  # Первая страница
page_2 = paginator.page(2)  # Вторая страница

# Выводим данные на странице 1
print(page_1.object_list)  # ['Товар 1', 'Товар 2', 'Товар 3', 'Товар 4', 'Товар 5']

# Проверяем, есть ли следующая страница
print(page_1.has_next())  # True
print(page_2.has_next())  # False

# Общая информация о пагинации
print(paginator.count)  # Общее количество объектов (12)
print(paginator.num_pages)  # Общее количество страниц (3)
print(page_1.number)  # Номер текущей страницы (1)

Важные методы объекта Paginator:

  • count: общее количество объектов.
  • num_pages: количество страниц.
  • page(number): получение объекта страницы по номеру.
  • has_next() и has_previous(): проверка наличия следующей или предыдущей страницы.

2. Пагинация в представлениях

Теперь мы готовы интегрировать пагинацию в приложение Django. Добавим пагинацию для списка объектов в нашем представлении.

Пример интеграции пагинации в представлении

Пусть у нас есть модель Product:

# models.py
from django.db import models

class Product(models.Model):
    name = models.CharField(max_length=100)
    price = models.DecimalField(max_digits=10, decimal_places=2)

    def __str__(self):
        return self.name

Добавим представление для отображения продуктов с пагинацией:

# views.py
from django.core.paginator import Paginator
from django.shortcuts import render
from .models import Product

def product_list_view(request):
    products = Product.objects.all()
    paginator = Paginator(products, 10)  # Показывать по 10 записей на странице

    page_number = request.GET.get('page')  # Получаем номер страницы из запроса
    page_obj = paginator.get_page(page_number)  # Получаем текущую страницу

    return render(request, 'product_list.html', {'page_obj': page_obj})

На что тут обратить внимание:

  • request.GET.get('page') — номер текущей страницы передается через GET-параметр.
  • paginator.get_page() — возвращает объект страницы, даже если номер страницы отсутствует или некорректен.

Шаблон для отображения

Теперь давайте добавим HTML-шаблон, который будет отображать данные с пагинацией:

<!-- templates/product_list.html -->
<!DOCTYPE html>
<html>
<head>
    <title>Список продуктов</title>
</head>
<body>
    <h1>Список продуктов</h1>
    <ul>
        {% for product in page_obj %}
            <li>{{ product.name }} - {{ product.price }} руб.</li>
        {% endfor %}
    </ul>

    <!-- Пагинация -->
    <div>
        {% if page_obj.has_previous %}
            <a href="?page={{ page_obj.previous_page_number }}">Предыдущая</a>
        {% endif %}

        <span>Страница {{ page_obj.number }} из {{ page_obj.paginator.num_pages }}</span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">Следующая</a>
        {% endif %}
    </div>
</body>
</html>

Этот шаблон выводит список продуктов, а ниже — элементы управления для перехода между страницами.

3. Улучшение пользовательского опыта

Пагинация работает, но давайте немного приблизим её к реальности. В реальных приложениях пользователи ожидают видеть номера страниц, чтобы сразу перейти к нужной.

<div>
    {% for num in page_obj.paginator.page_range %}
        {% if num == page_obj.number %}
            <strong>{{ num }}</strong> <!-- Текущая страница -->
        {% else %}
            <a href="?page={{ num }}">{{ num }}</a>
        {% endif %}
    {% endfor %}
</div>

Теперь пользователи смогут увидеть номера всех страниц и легко переключаться между ними.

Практическое задание

  1. Создайте новое Django-приложение для управления студентами. Назовите модель Student.
  2. Добавьте атрибуты first_name, last_name и grade (средний балл).
  3. Заполните базу данных тестовыми данными (например, 50 студентов).
  4. Настройте представление и шаблон для отображения студентов по 10 записей на странице.
  5. Реализуйте пагинацию с отображением номеров страниц.

Ваше приложение должно показывать список студентов с кнопками "Предыдущая", "Следующая" и номерами страниц (например, 1, 2, 3).

Совет:

пагинация часто случается в реальной жизни! Если вы справитесь с этим заданием, вас уже не напугает список из миллиона котиков (или студентов), который нужно разбить на страницы. И не забудьте протестировать пагинацию с пустым QuerySet — там тоже могут быть сюрпризы!

1
Задача
Модуль 3: Django, 8 уровень, 8 лекция
Недоступна
Реализация пагинации с фиксированным количеством элементов
Реализация пагинации с фиксированным количеством элементов
1
Задача
Модуль 3: Django, 8 уровень, 8 лекция
Недоступна
Динамическая пагинация через GET-параметры
Динамическая пагинация через GET-параметры
Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ