如何在drf-yasg中自定义符合指定结构的响应示例
实现drf-yasg响应外层统一包裹
data字段的方案 以下是两种常用的实现方案,可根据你的项目场景选择:
方案1:通用封装Serializer(适配性最高,推荐使用)
不需要修改全局配置,可灵活适配单个接口的需求,步骤如下:
- 第一步:定义通用的外层响应封装Serializer
from rest_framework import serializers class DataWrappedResponseSerializer(serializers.Serializer): """统一外层包裹data字段的响应Serializer""" data = serializers.SerializerMethodField() @classmethod def wrap(cls, inner_serializer_class): """动态绑定内层业务Serializer类型,生成封装后的响应结构""" return type( f"Wrapped{inner_serializer_class.__name__}", (cls,), {"data": inner_serializer_class()}, )
- 第二步:在接口的
swagger_auto_schema装饰器中指定封装后的响应Serializer即可
示例:假设你的业务响应Serializer为BookSerializer,接口写法如下:
from drf_yasg.utils import swagger_auto_schema from rest_framework.response import Response from rest_framework.views import APIView class BookDetailView(APIView): @swagger_auto_schema( operation_summary="获取书籍详情", responses={ 200: DataWrappedResponseSerializer.wrap(BookSerializer) } ) def get(self, request, *args, **kwargs): # 业务逻辑 book = Book.objects.get(id=kwargs.get("book_id")) # 实际接口返回也要对应包裹data字段 return Response({ "data": BookSerializer(book).data })
方案2:全局统一配置(适合全项目所有接口都使用该结构的场景)
如果你的项目所有接口都固定使用外层包data的结构,可通过重写drf-yasg的默认响应生成逻辑实现统一处理:
- 第一步:自定义Swagger响应生成类,重写响应结构的生成逻辑
from drf_yasg.inspectors import SwaggerAutoSchema class DataWrappedSwaggerAutoSchema(SwaggerAutoSchema): def get_responses(self): responses = super().get_responses() # 遍历所有响应码,统一包裹data字段 for status_code, response in responses.items(): if hasattr(response, 'schema') and response.schema is not None: original_schema = response.schema # 重写schema为外层包data的结构 wrapped_schema = { "type": "object", "properties": { "data": original_schema } } response.schema = wrapped_schema return responses
- 第二步:在Django settings中指定全局使用自定义的AutoSchema类
# settings.py SWAGGER_SETTINGS = { 'DEFAULT_AUTO_SCHEMA_CLASS': '你项目的对应存放路径.DataWrappedSwaggerAutoSchema', }
注意事项
- 如果是分页接口,只需要将分页Serializer传入方案1的
wrap方法即可,外层封装逻辑无需修改 - 如果需要对错误响应也做统一外层包裹,可在上述两种方案中对应扩展结构,增加
code、msg等通用字段即可
内容的提问来源于stack exchange,提问作者Кирилл Печурин
相关产品推荐
相关产品推荐

