如何用drf-yasg展示多个OpenAPI响应Schema方案?
用drf-yasg实现基于oneOf的多响应结构
没问题,你可以用drf-yasg(1.17.1版本)复现你需要的oneOf多响应结构,结合Django 2.2和Python 3.9的环境,具体实现步骤如下:
1. 先定义各类型库存的Serializer
首先为每个Stock类型编写DRF Serializer,这些Serializer会作为Swagger Schema的基础:
from rest_framework import serializers # 基础库存结构 class BaseStocksSerializer(serializers.Serializer): id = serializers.IntegerField() product_name = serializers.CharField() stock_quantity = serializers.IntegerField() # Apteka36.6库存结构 class Apteka366StocksSerializer(serializers.Serializer): id = serializers.IntegerField() pharmacy_id = serializers.CharField() available_stock = serializers.IntegerField() delivery_days = serializers.IntegerField() # 同理定义其他库存类型的Serializer # FarmiyaStocksSerializer、MailruStocksSerializer、NeofarmStocksSerializer...
2. 构造包含oneOf的响应Schema
使用drf-yasg提供的openapi模块,创建包含oneOf逻辑的响应结构:
方式一:直接构造OpenAPI Schema
在视图函数上用swagger_auto_schema装饰器,直接指定响应的Schema结构:
from drf_yasg.utils import swagger_auto_schema from drf_yasg import openapi from rest_framework.views import APIView from rest_framework.response import Response class StocksListView(APIView): @swagger_auto_schema( responses={ 200: openapi.Response( description="成功返回的多类型库存列表", schema=openapi.Schema( type=openapi.TYPE_OBJECT, properties={ "count": openapi.Schema(type=openapi.TYPE_INTEGER), "next": openapi.Schema(type=openapi.TYPE_STRING, nullable=True), "previous": openapi.Schema(type=openapi.TYPE_STRING, nullable=True), "results": openapi.Schema( type=openapi.TYPE_ARRAY, items=openapi.Schema( oneOf=[ openapi.SchemaRef(BaseStocksSerializer), openapi.SchemaRef(Apteka366StocksSerializer), openapi.SchemaRef(FarmiyaStocksSerializer), # 依次添加所有库存类型的Schema引用 ] ) ) } ) ) } ) def get(self, request): # 你的业务逻辑,根据请求返回对应类型的库存数据 return Response(data={"count": 10, "next": None, "previous": None, "results": []})
方式二:复用基础响应Serializer
如果你的基础响应结构(count/next/previous)固定,可以先定义一个基础响应Serializer,再替换results字段的Schema:
class BasePaginationResponseSerializer(serializers.Serializer): count = serializers.IntegerField() next = serializers.CharField(allow_null=True) previous = serializers.CharField(allow_null=True) results = serializers.ListField(child=serializers.DictField()) # 仅作为占位 # 在视图中使用 class StocksListView(APIView): @swagger_auto_schema( responses={ 200: openapi.Response( description="成功返回的多类型库存列表", schema=openapi.Schema.from_serializer(BasePaginationResponseSerializer).update( properties={ "results": openapi.Schema( type=openapi.TYPE_ARRAY, items=openapi.Schema( oneOf=[ openapi.SchemaRef(BaseStocksSerializer), openapi.SchemaRef(Apteka366StocksSerializer), # 其他库存Schema引用 ] ) ) } ) ) } ) def get(self, request): # 业务逻辑 return Response(...)
3. 关键注意点
- drf-yasg 1.17.1已经支持OpenAPI 3.0的
oneOf关键字,Swagger UI会正确渲染这个结构,显示为"Any Of"并展开所有可能的Schema。 - 使用
openapi.SchemaRef可以直接引用已定义的Serializer对应的Schema,避免重复编写字段定义。 - 注意
next和previous字段可能为null,需要在Schema中设置nullable=True,否则Swagger会将其标记为必填。
内容的提问来源于stack exchange,提问作者Gilions
相关产品推荐
相关产品推荐

