DRF修改列表Swagger Schema失败:自定义字段invoice_sum不显示
问题解决:drf-yasg 1.21.4下自定义分页字段无法在Swagger中显示
问题原因
drf-yasg 1.21.4版本不会自动调用DRF分页类的get_paginated_response_schema方法生成Swagger文档,尤其是当你用swagger_auto_schema装饰器覆盖list方法时,装饰器会优先使用自身配置的Schema,完全忽略分页类的自定义逻辑,这就是你看到方法未被调用、字段不显示的核心原因。
同时需要注意:即使Swagger显示了字段,实际接口也必须返回该字段才有用,所以需要同步修改分页响应的实际数据。
解决方案
方案一:手动在swagger_auto_schema中指定响应Schema
适合单视图定制,直接在装饰器中定义包含invoice_sum的分页响应Schema:
- 先定义基础的字段Schema和分页Schema
from drf_yasg import openapi from drf_yasg.utils import swagger_auto_schema # 替换为你的列表项实际字段Schema penalty_item_schema = openapi.Schema( type=openapi.TYPE_OBJECT, properties={ "id": openapi.Schema(type=openapi.TYPE_INTEGER, example=1), "penalty_amount": openapi.Schema(type=openapi.TYPE_NUMBER, example=50.0), # 其他模型字段... } ) # 带invoice_sum的分页响应Schema custom_paginated_schema = openapi.Schema( type=openapi.TYPE_OBJECT, properties={ "count": openapi.Schema(type=openapi.TYPE_INTEGER, example=20), "next": openapi.Schema(type=openapi.TYPE_STRING, example="http://example.com/api/penalties/?page=2"), "previous": openapi.Schema(type=openapi.TYPE_STRING, nullable=True, example=None), "results": openapi.Schema(type=openapi.TYPE_ARRAY, items=penalty_item_schema), "invoice_sum": openapi.Schema(type=openapi.TYPE_STRING, example="123.45"), } )
- 在视图的
list方法中使用,并确保实际响应返回invoice_sum
class PenaltiesView(XLSXFileMixin, ListOnlyModelViewSet): ... pagination_class = CustomPageNumberPagination @swagger_auto_schema( operation_summary='Summary', tags=['TAG1'], responses={200: custom_paginated_schema} ) def list(self, request, *args, **kwargs): queryset = self.filter_queryset(self.get_queryset()) page = self.paginate_queryset(queryset) if page is not None: serializer = self.get_serializer(page, many=True) response = self.get_paginated_response(serializer.data) # 计算并添加实际的invoice_sum值到响应 total_sum = queryset.aggregate(total=models.Sum('invoice_amount'))['total'] or 0.0 response.data['invoice_sum'] = f"{total_sum:.2f}" return response serializer = self.get_serializer(queryset, many=True) return Response(serializer.data)
方案二:全局自定义分页Inspector(批量生效)
适合多个视图需要相同分页Schema的场景,通过drf-yasg的Inspector扩展全局修改分页Schema:
- 自定义分页Inspector类
from drf_yasg.inspectors import PaginationInspector from drf_yasg import openapi class CustomPaginationInspector(PaginationInspector): def get_paginated_response(self, paginator, response_schema): # 获取默认分页Schema paginated_schema = super().get_paginated_response(paginator, response_schema) # 添加invoice_sum字段 paginated_schema['properties']['invoice_sum'] = openapi.Schema( type=openapi.TYPE_STRING, example='123.45' ) return paginated_schema
- 在
settings.py中配置drf-yasg的Inspector
SWAGGER_SETTINGS = { 'DEFAULT_PAGINATOR_INSPECTORS': [ 'your_app.path.to.CustomPaginationInspector', # 替换为你的Inspector路径 'drf_yasg.inspectors.DjangoRestResponsePagination', 'drf_yasg.inspectors.CoreAPICompatInspector', ], }
- 同步修改分页类的实际响应(必须做)
from rest_framework.pagination import PageNumberPagination from django.db.models import Sum class CustomPageNumberPagination(PageNumberPagination): def get_paginated_response(self, data): response = super().get_paginated_response(data) # 计算实际的invoice_sum total_sum = self.page.queryset.aggregate(total=Sum('invoice_amount'))['total'] or 0.0 response.data['invoice_sum'] = f"{total_sum:.2f}" return response # 可以删除get_paginated_response_schema方法,因为drf-yasg 1.21.4不会调用它
内容的提问来源于stack exchange,提问作者Альберт Александров
相关产品推荐
相关产品推荐

