如何使用drf-splant在django-rfw中生成自定义分页的模式



我正在努力为django-rest框架中的自定义分页正确生成模式。我正在使用drf壮观的模式生成。我的自定义分页包括一个总页数字段,该字段不随djangos PageNumberPagination一起提供。响应被正确地序列化和返回,并包括总页数,但我的swagger文档中的模式不包括该字段。这是我的代码:

分页.py

from rest_framework import pagination
from rest_framework.response import Response
class CustomPagination(pagination.PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
page_query_param = 'p'

def get_paginated_response(self, data):
return Response({
'page_size': self.page_size,
'total_objects': self.page.paginator.count,
'total_pages': self.page.paginator.num_pages,
'current_page_number': self.page.number,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'results': data,
})

这是我的观点:

视图.py

@extend_schema_view(
get=extend_schema(
parameters=[OpenApiParameter("q", OpenApiTypes.STR, OpenApiParameter.QUERY),],
request=TestStandardSearchSerializer,
responses=TestStandardSerializer
)
)
class TestStandardSearchView(ListAPIView):
serializer_class = TestStandardSearchSerializer
queryset = TestStandard.objects.all()
pagination_class = CustomPagination

def get(self, request, *args, **kwargs):
query = self.request.query_params.get('q')
queryset = SearchQuerySet().all().filter(content=query).order_by('acronym')
page = self.paginate_queryset(queryset)
serializer = self.get_serializer(page, many=True)
return self.get_paginated_response(serializer.data)

def get_serializer_class(self):
if self.request.method == 'GET':
return TestStandardSearchSerializer

我的swagger文档的响应模式如下:

PaginatedTestStandardList
{
count   integer                            example: 123
next    string($uri)     nullable: true    example: http://api.example.org/accounts/?p=4
previous    string($uri) nullable: true    example: http://api.example.org/accounts/?p=2
results [TestStandard{...}]
}

标准的django分页被正确地插入到模式中,但不是我的自定义分页响应。我期望/想要的是将我的自定义分页响应与总页数字段正确集成在"count"、"next"one_answers"previor"的同一级别。

我试过的。。。我有一个使用PaginatorInspector提供自定义模式的drf_yasg的工作解决方案。但这在drf壮观中不可用。我还将inline_serializer@extend_schema_view中的自定义响应一起使用,例如:

responses={
200: inline_serializer(
name='PaginatedTestStandardSearchResponse',
fields={
'total-pages': serializers.IntegerField(),
'results': TestStandardSearchSerializer()
},

这导致了一个架构,其中总页面嵌套在结果中。我正在使用:

drf-spectacular     0.21.2
Django              3.2.12
django-rest-swagger 2.2.0
djangorestframework 3.12.4

感谢您的帮助。我最近刚开始使用django-rfw和openapi模式生成。很抱歉我错过了一些显而易见的东西。

您需要覆盖CustomPagination中的方法get_paginated_response_schema。关于如何编写它的参考,您可以在rest_framework包中的文件pagination.py中看到它。

如果你想知道它是如何工作的,你可以在文件openapi.py的drf壮观包中找到它,方法为_get_response_for_code。我希望这能解决你的问题。

我最终覆盖了get_paginated_response((。这最终解决了我的问题。现在,正确的分页参数显示在swagger文档中。

这是我的自定义分页器:

from rest_framework import pagination
from rest_framework.response import Response
class CustomPagination(pagination.PageNumberPagination):
page_size = 10
page_size_query_param = 'page_size'
max_page_size = 100
page_query_param = 'p'

def get_paginated_response(self, data):
print(data)
print()
return Response({
'count': self.page.paginator.count,
'next': self.get_next_link(),
'previous': self.get_previous_link(),
'page_size': self.page_size,
'total_objects': self.page.paginator.count,
'total_pages': self.page.paginator.num_pages,
'current_page_number': self.page.number,
'results': data,
})

def get_paginated_response_schema(self, schema):            
return {
'type': 'object',
'properties': {
'count': {
'type': 'integer',
'example': 123,
},
'next': {
'type': 'string',
'nullable': True,
'format': 'uri',
'example': 'http://api.example.org/accounts/? 
{page_query_param}=4'.format(
page_query_param=self.page_query_param)
},
'previous': {
'type': 'string',
'nullable': True,
'format': 'uri',
'example': 'http://api.example.org/accounts/? 
{page_query_param}=2'.format(
page_query_param=self.page_query_param)
},                
'page_size' : {
'type': 'integer',
'example': 123,
},
'total_pages': {
'type': 'integer',
'example': 123,
},
'current_page_number': {
'type': 'integer',
'example': 123,
},
'results': schema,
},
}

当我面临相同的总页数问题时,我遵循了@Agung Wiyono的建议,下面的代码对我有效。它几乎与@Anti提供的代码相同,但使用了super。这样,我们只修改基本方法,而不完全重写它们。

class PageNumberPaginationWithCount(pagination.PageNumberPagination):
def get_paginated_response(self, *args, **kwargs):
response = super(PageNumberPaginationWithCount, self).get_paginated_response(*args, **kwargs)
response.data['total_pages'] = self.page.paginator.num_pages
return response
def get_paginated_response_schema(self, *args, **kwargs):
schema = super(PageNumberPaginationWithCount, self).get_paginated_response_schema(*args, **kwargs)
schema['properties']['total_pages'] = {
'type': 'integer',
'example': 123,
}
return schema

最新更新