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

如何在DRF Spectacular中为接口响应添加results键/名称

如何为DRF接口响应添加"results"外层键?

问题场景

我在DRF的extend_schema()中配置了如下接口响应:

patch = extend_schema(
    description='city',
    parameters=[
        OpenApiParameter("Accept-Language", OpenApiTypes.NUMBER, OpenApiParameter.HEADER),
        ],
    request={
        "application/json": inline_serializer(
            name="InlineOneCityPatchSerializer",
            fields={
                "country_id": serializers.IntegerField(),
            },
        ),
    },
    #responses = CityStateSerializer
    responses={
        200: OpenApiResponse(response=CityStateSerializer(many=True),
                             description='city response' ,),
        400: OpenApiResponse(description='Bad request (something invalid)'),
    },
),

当前接口返回的响应格式为:

[
  {
    "id": 0,
     ...
  }
]

我需要给响应添加名为results的外层键,让格式变成:

{
  "results": [
    {
      "id": 0,
       ...
    },
    {
      "id": 0,
       ...
    },
    {
      "id": 1,
       ...
    },
    {
      "id": 2,
       ...
    }
  ]
}

实现方案

方案1:自定义嵌套序列化器

先创建一个包裹原有序列化器的新序列化器,用来生成带results的结构:

class CityStateListSerializer(serializers.Serializer):
    results = CityStateSerializer(many=True)

接着更新extend_schema里的响应配置,替换原有的CityStateSerializer(many=True):

responses={
    200: OpenApiResponse(response=CityStateListSerializer(),
                         description='city response'),
    400: OpenApiResponse(description='Bad request (something invalid)'),
},

最后修改视图的返回逻辑,把原列表数据包裹在results键中:

# 原视图返回示例:return Response(serializer.data)
return Response({"results": serializer.data})

方案2:利用DRF分页类(适合需要分页的场景)

如果接口需要分页功能,直接用DRF内置分页类,默认就会返回带results键的结构:

  1. 全局配置分页(settings.py):
REST_FRAMEWORK = {
    'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
    'PAGE_SIZE': 10  # 根据需求设置每页条数
}

或者在单个视图中单独配置:

from rest_framework.pagination import PageNumberPagination

class CityView(APIView):
    pagination_class = PageNumberPagination

    def patch(self, request):
        # 业务逻辑处理
        queryset = City.objects.filter(...)
        page = self.paginate_queryset(queryset)
        if page is not None:
            serializer = CityStateSerializer(page, many=True)
            return self.get_paginated_response(serializer.data)
        # 无分页时也手动包裹results
        serializer = CityStateSerializer(queryset, many=True)
        return Response({"results": serializer.data})

这种方式下,extend_schema的响应配置会自动适配分页后的结构,也可以手动指定分页对应的序列化器。

方案3:用inline_serializer直接定义响应结构

如果不想单独创建序列化器,可直接在extend_schema里用inline_serializer定义带results的响应:

responses={
    200: OpenApiResponse(
        response=inline_serializer(
            name="CityStateListResponse",
            fields={
                "results": CityStateSerializer(many=True),
            },
        ),
        description='city response'
    ),
    400: OpenApiResponse(description='Bad request (something invalid)'),
},

同时记得修改视图返回数据为{"results": 序列化后的数据}。


内容的提问来源于stack exchange,提问作者Sadegh-khan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:02:26