如何在Django API Action中为特定请求方法指定响应Schema
解决DRF Spectacular多方法Action响应Schema不识别问题
你当前的写法中,extend_schema的responses用请求方法作为键不符合DRF Spectacular的规范,导致Swagger无法正确识别不同请求的响应结构。以下是两种可行的修复方案:
方案一:用extend_schema_view拆分方法配置
通过extend_schema_view可以给每个HTTP方法单独定义Schema配置,是最清晰的方式:
from drf_spectacular.utils import extend_schema, extend_schema_view from drf_spectacular.utils import get_paginated_response_schema class SessionsViewSet(viewsets.ModelViewSet): ... @extend_schema_view( get=extend_schema( parameters=[query_params["extra_query_param"]], # GET返回分页列表,用get_paginated_response_schema适配分页结构 responses=get_paginated_response_schema(serializers.ExampleSerializer(many=True)) ), post=extend_schema( responses=serializers.ExampleSerializer(many=False) ) ) @action( detail=True, url_path="example", methods=["GET", "POST"], filter_backends=[], ) def example(self, request, pk, *args, **kwargs): match request.method: case "GET": queryset = MyModel.objects.filter(session_pk_id=pk) page = self.paginate_queryset(queryset) serializer = get_serializer(page, many=True) return self.get_paginated_response(serializer.data) case "POST": serializer = get_serializer(data=request.data, many=False) if serializer.is_valid(): serializer.save() return Response( serializer.data, status=status.HTTP_201_CREATED, ) else: return Response( serializer.errors, status=status.HTTP_400_BAD_REQUEST ) case _: return Response(status=status.HTTP_405_METHOD_NOT_ALLOWED)
方案二:在extend_schema中用状态码映射响应
DRF Spectacular的responses参数默认以HTTP状态码为键,你可以通过状态码区分不同请求的成功响应,同时用OpenApiResponse明确描述:
from drf_spectacular.utils import extend_schema, OpenApiResponse, get_paginated_response_schema class SessionsViewSet(viewsets.ModelViewSet): ... @extend_schema( parameters=[query_params["extra_query_param"]], responses={ 200: OpenApiResponse( response=get_paginated_response_schema(serializers.ExampleSerializer(many=True)), description="GET请求返回分页实体列表" ), 201: OpenApiResponse( response=serializers.ExampleSerializer(many=False), description="POST请求返回创建的实体" ), 400: OpenApiResponse(description="请求参数验证失败"), 405: OpenApiResponse(description="不允许的请求方法") }, methods=["GET", "POST"] ) @action( detail=True, url_path="example", methods=["GET", "POST"], filter_backends=[], ) def example(self, request, pk, *args, **kwargs): # 原方法逻辑不变
关键说明
- 不要用请求方法(如"GET"/"POST")作为
responses的键,DRF Spectacular不支持这种映射方式; - 如果GET请求使用了分页,必须用
get_paginated_response_schema包裹序列化器,否则Swagger会显示错误的响应结构; extend_schema_view更适合多方法Action的Schema拆分,可读性和维护性更好。
内容的提问来源于stack exchange,提问作者Austin Hallett
相关产品推荐
相关产品推荐

