drf-yasg:在 Swagger 文档中显示 ListAPIView 的自定义分页
drf-yasg: Show custom pagination for ListAPIView in Swagger docs
我在 Django REST 框架中有以下列表API视图和自定义分页class:
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
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 文档中显示自定义分页 class。
我已经从 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']
)
因为我正在使用其他列表API视图,默认分页 class 在 settings.py 中指定,自定义分页 class 应该只用于列表API查看“价格趋势”。
解决方法如下:
- 创建自定义分页器检查器
分页检查器
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']
)
- 覆盖 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)
我在 Django REST 框架中有以下列表API视图和自定义分页class:
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
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 文档中显示自定义分页 class。
我已经从 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']
)
因为我正在使用其他列表API视图,默认分页 class 在 settings.py 中指定,自定义分页 class 应该只用于列表API查看“价格趋势”。
解决方法如下:
- 创建自定义分页器检查器
分页检查器
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']
)
- 覆盖 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)