Если вдруг забыли, пагинация — это техника, используемая для разделения больших объемов данных на более управляемые и удобные для обработки части (например, страницы). Она позволяет клиенту получить только нужную часть данных, экономя ресурсы сервера и клиента. С точки зрения сервера, это уменьшает нагрузку на обработку запроса. С точки зрения клиента — ускоряет получение ответа и делает данные более структурированными.
Пагинация в Django REST Framework (DRF)
Django REST Framework поддерживает пагинацию "из коробки". DRF предоставляет несколько встроенных механизмов пагинации, которые позволяют легко интегрировать этот функционал в ваше API. Итак, представьте, что вы получили подарок, и внутри коробки лежат три игрушки:
- PageNumberPagination — страничная пагинация (передача номера страницы).
- LimitOffsetPagination — пограничная пагинация (лимит записей и смещение).
- CursorPagination — курсорная пагинация (использование курсора для навигации по результатам).
Каждый из этих методов имеет свои плюсы и идеально подходит для разных сценариев. В этой лекции мы сосредоточимся на понимании базовых принципов пагинации и основных её методах.
Классы пагинации в DRF
DRF предоставляет классы для настройки пагинации. Вот три основных класса, которые вы увидите в реальных проектах:
PageNumberPagination
Пользователь запрашивает номер страницы (например,page=2) и получает часть данных, относящихся к этой странице. Это самый распространённый и понятный вид пагинации.LimitOffsetPagination
Клиент указывает два параметра:limit— количество элементов, которые нужно получить.offset— с какого элемента начинать выборку.
Например, запрос?limit=10&offset=20вернет 10 записей, начиная с 21-й.
CursorPagination
Для этой пагинации используются уникальные курсоры, которые позволяют клиенту переходить вперёд или назад по результатам. Этот метод более безопасен и удобен для работы с данными, которые могут изменяться (например, новые записи добавляются в базу).
Как это выглядит в реальной жизни?
Давайте представим: у вас есть API для просмотра списка фильмов с тысячи записей. Без пагинации, запрос к /api/movies/ возвращает ВСЕ записи, что приводит к задержкам и увеличению трафика. С пагинацией же запросы будут выглядеть так:
/api/movies/?page=1— данные для первой страницы./api/movies/?page=2— данные для второй страницы.
Или:
/api/movies/?limit=10&offset=0— первые 10 записей./api/movies/?limit=10&offset=10— следующие 10 записей.
Настроить пагинацию в DRF проще, чем объяснить маме, зачем нужно обновлять Windows… Вам нужно всего лишь включить её в вашем Django-проекте.
Практическое применение: добавление пагинации
Мы будем пошагово добавлять пагинацию в наше API для списка фильмов. Код нашего API уже существует (вы создавали его в предыдущих лекциях). Теперь пришло время вставить туда магическую штуку под названием пагинация.
Шаг 1: настройка глобальной пагинации
Для начала добавим глобальную настройку пагинации. Это значит, что пагинация будет работать для каждого эндпоинта API по умолчанию.
Открываем файл settings.py и добавляем следующие настройки:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination', # Выбираем тип пагинации
'PAGE_SIZE': 10, # Количество элементов на одной странице
}
Теперь при запросе к вашему API на любом эндпоинте, возвращающем списки, будет применяться пагинация с 10 элементами на странице.
Шаг 2: проверяем работу пагинации
Если вы выполните запрос к вашему API (например, http://127.0.0.1:8000/api/movies/), то вместо одной бесконечной простыни данных вы увидите следующее:
{
"count": 100,
"next": "http://127.0.0.1:8000/api/movies/?page=2",
"previous": null,
"results": [
{
"id": 1,
"title": "Interstellar",
"year": 2014
},
...
]
}
count: общее количество записей.next: ссылка на следующую страницу.previous: ссылка на предыдущую страницу.results: данные текущей страницы.
Элегантно, не правда ли?
Шаг 3: локальная настройка пагинации
Если у вас есть эндпоинт, который нужно настроить по-другому (например, выдавать 5 записей на странице, а не 10), это можно сделать локально для конкретного представления (view).
Давайте изменим пагинацию для списка фильмов. Открываем views.py:
from rest_framework.pagination import PageNumberPagination
from rest_framework.generics import ListAPIView
from .models import Movie
from .serializers import MovieSerializer
class CustomPagination(PageNumberPagination):
page_size = 5 # Устанавливаем 5 записей на страницу
class MovieListView(ListAPIView):
queryset = Movie.objects.all()
serializer_class = MovieSerializer
pagination_class = CustomPagination # Используем нашу кастомную пагинацию
Теперь запрос к /api/movies/ вернет только 5 записей на одной странице. А глобальные настройки не будут затронуты.
Итоги
Пагинация — ключевая часть любого API. Если вы забыли её настроить, клиенты вашего API могут "наказать" вас медленными запросами и жалобами. А ещё это просто удобно: когда клиент видит ссылки на next и previous, он чувствует себя, как в уютной библиотеке, где всё упорядочено. DRF позаботится о вас, давая возможность настроить пагинацию всего за несколько строк кода.
Теперь, улыбайтесь, ведь вы стали на шаг ближе к созданию настоящего, профессионального API!
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ