You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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:

  1. 先定义基础的字段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"),
    }
)
  1. 在视图的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:

  1. 自定义分页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
  1. 在settings.py中配置drf-yasg的Inspector
SWAGGER_SETTINGS = {
    'DEFAULT_PAGINATOR_INSPECTORS': [
        'your_app.path.to.CustomPaginationInspector',  # 替换为你的Inspector路径
        'drf_yasg.inspectors.DjangoRestResponsePagination',
        'drf_yasg.inspectors.CoreAPICompatInspector',
    ],
}
  1. 同步修改分页类的实际响应(必须做)
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,提问作者Альберт Александров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.28 02:14:58