1

Currently I'm using LimitOffsetPagination on drf, and documenting the API with drf-yasg.

I wrote a View like this:

class MyViewSet(GenericViewSet):
    @action(detail=False, methods=['get'])
    def submodel1(self, request):
        queryset = SubModel1.objects.filter(user=request.user)
        queryset = self.paginate_queryset(queryset.all())

        serializer = SubModel1Serializer(queryset, many=True)
        return self.get_paginated_response(serializer.data)

    @action(detail=False, methods=['get'])
    def submodel2(self, request):
        queryset = SubModel2.objects.filter(user=request.user)
        queryset = self.paginate_queryset(queryset.all())

        serializer = SubModel2Serializer(queryset, many=True)
        return self.get_paginated_response(serializer.data)

Now I would like to document it using swagger_auto_schema.

I wonder is there a way to generate/add the paginated response schema and parameters automatically on those action views.

If I use SubModel1Serializer(many=True) on swagger_auto_schema(responses={...}), the response schema will only show as an array of SubModel1s(or 2s), not having fields such as prev, next, items.

Thank you.

Ruby Cho
  • 25
  • 3
  • 6

1 Answers1

3

We would need to create a paginator inspector class and provide it under paginator_inspectors argument to swagger_auto_schema or one can add that paginator class to global settings under DEFAULT_PAGINATOR_INSPECTORS in SWAGGER_SETTINGS. I myself have created a paginator class, would provide as an example here. I followed LimitOffsetPagination.


from drf_yasg.inspectors import PaginatorInspector
from drf_yasg import openapi


class LimitOffsetPaginatorInspectorClass(PaginatorInspector):

    def get_paginated_response(self, paginator, response_schema):
        """
        :param BasePagination paginator: the paginator
        :param openapi.Schema response_schema: the response schema that must be paged.
        :rtype: openapi.Schema
        """

        return openapi.Schema(
            type=openapi.TYPE_OBJECT,
            properties=OrderedDict((
                ('count', openapi.Schema(type=openapi.TYPE_INTEGER)),
                ('next', openapi.Schema(
                    type=openapi.TYPE_OBJECT,
                    properties=OrderedDict((
                        ('offset', openapi.Schema(type=openapi.TYPE_INTEGER)),
                        ('limit', openapi.Schema(type=openapi.TYPE_INTEGER))
                    ))
                )),
                ('results', response_schema),
            )),
            required=['results']
        )

    def get_paginator_parameters(self, paginator):
        """
        Get the pagination parameters for a single paginator **instance**.

        Should return :data:`.NotHandled` if this inspector does not know how to handle the given `paginator`.

        :param BasePagination paginator: the paginator
        :rtype: list[openapi.Parameter]
        """

        return [
            openapi.Parameter('offset', openapi.IN_QUERY, "Offset for Pagination", False, None, openapi.TYPE_INTEGER),
            openapi.Parameter('limit', openapi.IN_QUERY, "Page Size", False, None, openapi.TYPE_INTEGER)
        ]```