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

如何使用drf-yasg配置适配自定义标准API响应的接口文档

配置步骤

1. 定义通用响应序列化器

首先新建工具文件(比如yasg_utils.py),定义三个基础序列化器对应要求的三种响应结构:

from rest_framework import serializers
from drf_yasg import openapi

# 单条查询成功响应序列化器
class SingleSuccessResponseSerializer(serializers.Serializer):
    status = serializers.IntegerField(help_text="http状态码,可取值201、200等")
    success = serializers.BooleanField(help_text="标识请求是否成功")
    message = serializers.CharField(allow_null=True, help_text="成功提示信息,可为null")
    result = serializers.SerializerMethodField(help_text="响应数据字典")

# 分页列表查询成功响应序列化器
class PaginatedSuccessResponseSerializer(serializers.Serializer):
    status = serializers.IntegerField(help_text="http状态码")
    success = serializers.BooleanField(help_text="标识请求是否成功")
    message = serializers.CharField(allow_null=True, help_text="提示信息,可为null")
    results = serializers.ListSerializer(child=serializers.SerializerMethodField(), help_text="数据列表")
    count = serializers.IntegerField(help_text="数据总条数")
    page_size = serializers.IntegerField(help_text="每页最大条数")
    current_page = serializers.IntegerField(help_text="当前页码")
    next = serializers.URLField(allow_null=True, help_text="下一页链接,可为null")
    previous = serializers.URLField(allow_null=True, help_text="上一页链接,可为null")

# 错误响应序列化器
class ErrorResponseSerializer(serializers.Serializer):
    status = serializers.IntegerField(help_text="http状态码,可取值403、404、500等")
    success = serializers.BooleanField(help_text="标识请求是否成功")
    message = serializers.CharField(allow_null=True, help_text="失败提示信息,可为null")
    result = serializers.DictField(help_text="错误相关数据字典")

2. 封装通用响应构造工具

在同一工具文件中添加通用构造函数,自动把接口原返回结构嵌套到统一响应中,同时内置示例:

# 通用错误响应配置
error_response = {
    400: openapi.Response(
        description='请求参数错误',
        schema=ErrorResponseSerializer,
        examples={
            'application/json': {
                "status": 400,
                "success": False,
                "message": "The failed message",
                "result": {}
            }
        }
    ),
    401: openapi.Response(description='未登录', schema=ErrorResponseSerializer),
    403: openapi.Response(description='无操作权限', schema=ErrorResponseSerializer),
    404: openapi.Response(description='资源不存在', schema=ErrorResponseSerializer),
}

def wrap_response_schema(data_schema, is_list=False):
    """
    把接口原返回schema包裹到统一响应结构中
    :param data_schema: 接口原返回序列化器/OpenAPI Schema对象
    :param is_list: 是否为分页列表接口
    """
    if is_list:
        return openapi.Response(
            description='分页查询成功响应',
            schema=PaginatedSuccessResponseSerializer,
            examples={
                'application/json': {
                    "status": 200,
                    "success": True,
                    "message": None,
                    "results": [],
                    "count": 2,
                    "page_size": 5,
                    "current_page": 1,
                    "next": "http://127.0.0.1:8000/api/page/?page=2&search=a",
                    "previous": None
                }
            }
        )
    else:
        return openapi.Response(
            description='操作成功响应',
            schema=SingleSuccessResponseSerializer,
            examples={
                'application/json': {
                    "status": 200,
                    "success": True,
                    "message": "The success message",
                    "result": {}
                }
            }
        )

3. 两种配置方案二选一

方案A:单个接口手动配置(灵活度高)

适合仅部分接口需要展示统一结构的场景,直接给视图方法加swagger_auto_schema装饰器指定响应即可:

from drf_yasg.utils import swagger_auto_schema
from .yasg_utils import wrap_response_schema, error_response
from .serializers import UserSerializer

class UserViewSet(ModelViewSet):
    queryset = User.objects.all()
    serializer_class = UserSerializer

    # 单条查询接口
    @swagger_auto_schema(
        responses={
            200: wrap_response_schema(UserSerializer),
            **error_response
        }
    )
    def retrieve(self, request, *args, **kwargs):
        return super().retrieve(request, *args, **kwargs)

    # 分页列表接口
    @swagger_auto_schema(
        responses={
            200: wrap_response_schema(UserSerializer, is_list=True),
            **error_response
        }
    )
    def list(self, request, *args, **kwargs):
        return super().list(request, *args, **kwargs)

方案B:全局自动配置(无需逐个接口修改)

适合所有接口都需要统一结构的场景,自定义AutoSchema类重写响应生成逻辑,然后修改你现有urls.py中的schema_view配置即可:
首先在yasg_utils.py中添加自定义AutoSchema:

from drf_yasg.inspectors import SwaggerAutoSchema

class CustomSwaggerAutoSchema(SwaggerAutoSchema):
    def get_responses(self):
        responses = super().get_responses()
        # 自动包裹成功响应结构
        for status_code in list(responses.keys()):
            if 200 <= status_code < 300:
                original_schema = responses[status_code]["schema"]
                is_list = self.action == "list"
                responses[status_code] = wrap_response_schema(original_schema, is_list=is_list)
        # 统一追加错误响应
        responses.update(error_response)
        return responses

然后修改你原有urls.py中的schema_view配置,指定使用自定义的AutoSchema:

from .yasg_utils import CustomSwaggerAutoSchema

# 原有代码不变,仅修改get_schema_view部分
schema_view = get_schema_view(
    info=swagger_info,
    public=True,
    permission_classes=(permissions.IsAdminUser,),
    authentication_classes=(authentication.SessionAuthentication,),
    # 新增以下配置
    auto_schema=CustomSwaggerAutoSchema
)

内容的提问来源于stack exchange,提问作者binpy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 04:24:01