如何基于序列化器(drf-yasg)获取分页响应模式
how to get paginated response schema based on serializer (drf-yasg)
目前我在 drf 上使用 LimitOffsetPagination,并使用 drf-yasg 记录 API。
我写了一个这样的视图:
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)
现在我想使用 swagger_auto_schema
来记录它。
我想知道有没有办法 generate/add 在这些操作视图上自动 generate/add 分页响应架构和参数。
如果我在 swagger_auto_schema(responses={...})
上使用 SubModel1Serializer(many=True)
,响应模式将仅显示为 SubModel1(或 2)的数组,没有上一个、下一个、项目等字段。
谢谢。
解决方案是在一个视图集上有多个查询集和序列化程序。
querysets = {
'submodel1': SubModel1.objects.all(),
'submodel2': SubModel2.objects.all()
}
serializer_classes = {
'submodel1': SubModel1Serializer,
'submodel2': SubModel2Serializer
}
def get_queryset(self):
if self.action in self.querysets:
return self.querysets[self.action]
return super().get_queryset()
def get_serializer_class(self):
if self.action in self.querysets:
return self.serializer_classes[self.action]
return super().get_serializer_class()
它就像魔法一样奏效。 (❁´◡`❁)
我们需要创建一个分页器检查器 class 并在 paginator_inspectors
参数下将其提供给 swagger_auto_schema
或者可以将该分页器 class 添加到 DEFAULT_PAGINATOR_INSPECTORS
在 SWAGGER_SETTINGS
中。我自己创建了一个分页器 class,将在此处作为示例提供。我关注了 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)
]```
目前我在 drf 上使用 LimitOffsetPagination,并使用 drf-yasg 记录 API。
我写了一个这样的视图:
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)
现在我想使用 swagger_auto_schema
来记录它。
我想知道有没有办法 generate/add 在这些操作视图上自动 generate/add 分页响应架构和参数。
如果我在 swagger_auto_schema(responses={...})
上使用 SubModel1Serializer(many=True)
,响应模式将仅显示为 SubModel1(或 2)的数组,没有上一个、下一个、项目等字段。
谢谢。
解决方案是在一个视图集上有多个查询集和序列化程序。
querysets = {
'submodel1': SubModel1.objects.all(),
'submodel2': SubModel2.objects.all()
}
serializer_classes = {
'submodel1': SubModel1Serializer,
'submodel2': SubModel2Serializer
}
def get_queryset(self):
if self.action in self.querysets:
return self.querysets[self.action]
return super().get_queryset()
def get_serializer_class(self):
if self.action in self.querysets:
return self.serializer_classes[self.action]
return super().get_serializer_class()
它就像魔法一样奏效。 (❁´◡`❁)
我们需要创建一个分页器检查器 class 并在 paginator_inspectors
参数下将其提供给 swagger_auto_schema
或者可以将该分页器 class 添加到 DEFAULT_PAGINATOR_INSPECTORS
在 SWAGGER_SETTINGS
中。我自己创建了一个分页器 class,将在此处作为示例提供。我关注了 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)
]```