如何使用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
相关产品推荐
相关产品推荐

