Курс по Django: https://stepik.org/a/183363
На этом занятии
мы рассмотрим возможность разбивки списка данных на отдельные страницы.
Например, у нас имеется API-запрос на список известных женщин:
http://127.0.0.1:8000/api/v1/women/
Понятно, что в
БД может быть огромное количество записей по женщинам и выдавать их все по
данному запросу было бы крайне неразумно из-за слишком большого объема данных.
Для этого и вводится пагинация, то есть, разбивка на отдельные страницы по
несколько записей на каждой. И как это сделать в рамках Django REST Framework мы сейчас
увидим.
Конечно, в
официальной документации можно подробно почитать, как подключается пагинация к
проекту:
https://www.django-rest-framework.org/api-guide/pagination/
Я прямо буду ей
следовать. Фактически, все что нам нужно, это прописать в словаре REST_FRAMEWORK, следующие
строчки:
REST_FRAMEWORK = {
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
'PAGE_SIZE': 2,
...
}
Ключ 'DEFAULT_PAGINATION_CLASS' позволяет
задать класс пагинации, который будет применяться по умолчанию к выдаваемым
спискам данных. В Django REST Framework имеется
встроенный класс LimitOffsetPagination и мы его здесь указываем. Второй
ключ 'PAGE_SIZE' задает число записей (в нашем случае женщин) на странице. Я
указал два, чтобы мы могли видеть пагинацию в действии.
Запустим,
теперь, тестовый веб-сервер:
python manage.py runserver
и откроем в
браузере страницу:
http://127.0.0.1:8000/api/v1/women/
Как видите, у
нас здесь с вами отобразился только первый фрагмент списка из двух записей.
Кроме того, в JSON-ответе мы видим
параметры:
-
"count"
– общее
число записей;
-
"next"
– ссылка на следующую страницу;
-
"previous"
– ссылка на предыдущую страницу;
-
"results"
– набор данных.
Также средства DRF позволяют нам в
интерактивном режиме в браузере переключаться по страницам и просматривать их
содержимое.
Однако, обратите
внимание, такая пагинация будет автоматически применяться к каждому API-запросу, где
идет вывод списка данных. Например, у нас есть запрос для списка
зарегистрированных пользователей:
http://127.0.0.1:8000/api/v1/auth/users/
и здесь мы тоже
видим включенный режим пагинации.
Но, если открыть
страницу с одной записью:
http://127.0.0.1:8000/api/v1/women/9/
то никакой
пагинации не будет, т.к. здесь нет списка записей в ответе.
Пользовательские классы пагинации
Конечно, нам
может потребоваться для определенных API-запросов настраивать свои
параметры пагинации. Это делается достаточно просто с помощью определения
собственных классов пагинации и подключения их к нужным видам. Давайте сделаем
это для класса WomenAPIList.
Вначале
определим свой класс пагинации WomenAPIListPagination, который унаследуем
от базового класса в DRF – PageNumberPagination:
class WomenAPIListPagination(PageNumberPagination):
page_size = 3
page_size_query_param = 'page_size'
max_page_size = 10000
Здесь:
-
page_size – число записей
на страницу;
-
page_size_query_param – параметр
запроса, в котором можно настраивать количество выдаваемых записей на страницу;
-
max_page_size – максимальное количество
записей на странице для запроса page_size_query_param.
Сейчас мы
увидим, как все это работает. Подключим класс пагинации в классе WomenAPIList:
class WomenAPIList(generics.ListCreateAPIView):
queryset = Women.objects.all()
serializer_class = WomenSerializer
permission_classes = (IsAuthenticatedOrReadOnly, )
pagination_class = WomenAPIListPagination
и в браузере откроем
страницу:
http://127.0.0.1:8000/api/v1/women/
Видим, что
выдается по три записи на странице, как это и настроено в нашем
пользовательском классе. Но мы также можем выполнить и такой запрос:
http://127.0.0.1:8000/api/v1/women/?page_size=4
Здесь
дополнительно прописан параметр page_size со значением 4.
Теперь у нас на странице будет по четыре записи. Этот параметр можно
использовать, если клиент пожелает изменить число выдаваемых записей на
странице. Но их будет не более max_page_size. Например, если
этот параметр установить в два:
то получим
максимум две записи, несмотря на то, что page_size=4. В результате, мы на
стороне сервера ограничиваем максимальный выдаваемый объем данных –
своеобразная «защита от дурака», если клиент запросит слишком большой объем.
Вот так,
достаточно просто, можно реализовать пагинацию в Django REST Framework и теперь,
уверен, каждый из вас сможет это сделать в своем проекте.
Курс по Django: https://stepik.org/a/183363