Django 5 для начинающих

Прогресс по курсу:  9/1004

8.6 Пагинация
3 из 3 шагов пройдено

Пагинация

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

API пагинации может поддерживать любую из этих функций:

  • Ссылки пагинации, которые предоставляются как часть содержимого ответа.

  • Ссылки пагинации, включенные в заголовки ответа, такие как Content-Range или Link.

В настоящее время все встроенные стили используют ссылки, включенные как часть содержимого ответа. Этот стиль более доступен при использовании API с возможностью просмотра.

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

Если вы используете обычное APIView, вам нужно будет самостоятельно обратиться к API пагинации, чтобы убедиться, что вы возвращаете ответ с пагинацией. Пример смотрите в исходном коде классов mixins.ListModelMixin и generics.GenericAPIView.

Пагинацию можно отключить, установив для класса пагинации значение None.

 

Установка стиля пагинации

Стиль пагинации можно задать глобально, используя ключи настройки DEFAULT_PAGINATION_CLASS и PAGE_SIZE.

Например, чтобы использовать встроенную пагинацию с ограничением/смещением, вы должны сделать следующее, в файле settings.py добавить строки:

REST_FRAMEWORK = {
    "DEFAULT_PERMISSION_CLASSES": [
        "rest_framework.permissions.AllowAny",
    ],
    'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],

    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',  # new
    'PAGE_SIZE': 3   # new
}

Обратите внимание, что необходимо задать как класс пагинации, так и размер страницы, которая будет использоваться. По умолчанию и DEFAULT_PAGINATION_CLASS, и PAGE_SIZE имеют значение None:

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

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

Изменение стиля пагинации

Например, если вы захотите изменить определенные аспекты стиля пагинации, вам нужно переопределить один из классов пагинации и установить атрибуты, которые вы хотите изменить:

from rest_framework.pagination import PageNumberPagination


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 5
    page_size_query_param = 'page_size'
    max_page_size = 10

И затем вы можете применить ваш новый стиль к представлению с помощью атрибута pagination_class:

class PostList(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['author']
    search_fields = ['body', 'author__profile__bio']
    ordering_fields = ['author_id', 'publish']
    ordering = ['body']
    pagination_class = StandardResultsSetPagination # new

Тем самым мы переопределяем настройки нашей пагинации.


  • Комментариев
Будьте вежливы и соблюдайте наши принципы сообщества. Пожалуйста, не оставляйте решения и подсказки в комментариях, для этого есть отдельный форум.
Оставить комментарий

А пагинация нам в АПИ зачем? Тоже для отладки? Или когда вытягиваешь данные с пагинацией в условное мобильное приложение, там они уже тоже будут разбиты постранично? 

@Георгий_Тимофеев, да, как-раз для этого, иначе пришлось бы разбирать в приложении несколько тысяч постов(а может и больше), что явно не разумно.

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

Тут или какая-то опечатка в тексте или я не понимаю, что это значит?  

@Георгий_Тимофеев, спасибо, исправил.

Добавлю здесь, хотя это есть на следующем шаге:

from rest_framework.pagination import PageNumberPagination


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 5
    page_size_query_param = 'page_size'
    max_page_size = 10
  • page_size - Числовое значение, указывающее размер страницы. Если установлено, оно отменяет настройку PAGE_SIZE. По умолчанию имеет то же значение, что и ключ настройки PAGE_SIZE.

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

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

Изменен Кирилл Семенихин

тут тоже самое поправьте пожалуйста куда это нужно вставлять?

 

Изменение стиля пагинации

Если вы хотите изменить определенные аспекты стиля пагинации, вам нужно переопределить один из классов пагинации и установить атрибуты, которые вы хотите изменить:

from rest_framework.pagination import PageNumberPagination


class StandardResultsSetPagination(PageNumberPagination):
    page_size = 5
    page_size_query_param = 'page_size'
    max_page_size = 10

Затем вы можете применить ваш новый стиль к представлению с помощью атрибута pagination_class:

class PostList(generics.ListCreateAPIView):
    queryset = Post.objects.all()
    serializer_class = PostSerializer
    filter_backends = [DjangoFilterBackend, filters.SearchFilter, filters.OrderingFilter]
    filterset_fields = ['author']
    search_fields = ['body', 'author__profile__bio']
    ordering_fields = ['author_id', 'publish']
    ordering = ['body']
    pagination_class = StandardResultsSetPagination # new

Тем самым мы переопределяем настройки нашей пагинации.

@No_Name, Поправил в лекции, этот подраздел сделан в качестве примера использования кастомных параметров пагинации.

Откуда импортировать PageNumberPagination?

@Марат_Асылбаев,

from rest_framework.pagination import PageNumberPagination