如何在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键的结构:
- 全局配置分页(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
相关产品推荐
相关产品推荐

