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

如何在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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 21:47:28