【问题标题】:drf-yasg: Show custom pagination for ListAPIView in Swagger docsdrf-yasg:在 Swagger 文档中显示 ListAPIView 的自定义分页
【发布时间】:2021-05-13 10:31:07
【问题描述】:

我在 Django REST 框架中有以下 ListAPIView 和自定义分页类:

views.py

class pricetrend(generics.ListAPIView):
    queryset = Variants.objects.annotate(timestamp=TruncMonth('variantTimestamp')).values('timestamp').annotate(average_price=Avg('price'))
    serializer_class = PricetrendSerializer
    pagination_class = PricesPagination

自定义分页类

class PricesPagination(PageNumberPagination):
    page_size = 10
    page_size_query_param = 'page_size'

    def get_paginated_response(self, data):
        prices = [dict(item)['average_price'] for item in data]
        try:
            total_average_price = sum(prices)/ len(prices)
        except Exception as e:
            total_average_price = 0
        return Response({
            'count': self.page.paginator.count,
            'next': self.get_next_link(),
            'previous': self.get_previous_link(),
            'total_average_price': round(total_average_price),
            'results': data,
        })

目前,我正在尝试弄清楚如何在 drf-yasg 生成的 Swagger API 文档中显示自定义分页类。

我已经从 drf_yasg.inspectors 自定义了 PaginatorInspector,但不知道我需要把它放在哪里才能将它用于上述 ListAPIView。

自定义 PaginatorInspector

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) if has_count else None),
                ('next', openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_URI, x_nullable=True)),
                ('previous', openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_URI, x_nullable=True)),
                ('total_average_price', openapi.Schema(type=openapi.TYPE_INTEGER)),
                ('results', response_schema),
            )),
            required=['results']
        )

由于我使用其他 ListAPIViews 并在 settings.py 中指定了默认分页类,因此自定义分页类应仅用于 ListAPIView“价格趋势”。

【问题讨论】:

    标签: django django-rest-framework django-views drf-yasg django-swagger


    【解决方案1】:

    解决如下:

    1. 创建自定义分页检查器

    分页检查器

    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_STRING, format=openapi.FORMAT_URI, x_nullable=True)),
                ('previous', openapi.Schema(type=openapi.TYPE_STRING, format=openapi.FORMAT_URI, x_nullable=True)),
                ('total_average_price', openapi.Schema(type=openapi.TYPE_INTEGER)),
                ('results', response_schema),
            )),
            required=['results']
        )
    
    1. 重写 ListAPIView 以便能够使用 @swagger_auto_schema 指定自定义分页器检查器

    views.py

    class pricetrend(generics.ListAPIView):
        queryset = Variants.objects.annotate(timestamp=TruncMonth('variantTimestamp')).values('timestamp').annotate(average_price=Avg('price'))
        serializer_class = PricetrendSerializer
        pagination_class = PricesPagination
        @swagger_auto_schema(pagination_class=PricesPagination, paginator_inspectors=[LimitOffsetPaginatorInspectorClass])
        def get(self, request, *args, **kwargs):
            queryset = self.filter_queryset(self.get_queryset())
            page = self.paginate_queryset(queryset)
            serializer = PricetrendSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
    

    【讨论】:

      猜你喜欢
      • 2022-12-14
      • 2018-07-19
      • 1970-01-01
      • 1970-01-01
      • 2021-07-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-13
      相关资源
      最近更新 更多