如何自定义Django DRF AutoSchema的字段表示形式
DRF 自定义Choice字段OpenAPI枚举说明实现方案
你可以通过重写DRF内置AutoSchema类的字段映射逻辑实现需求,全程不需要修改核心源码,步骤如下:
- 第一步:先规范你的Choice字段选项定义
不管是直接定义在Serializer上的ChoiceField,还是ModelSerializer从模型字段继承的choices,都要保证选项为(枚举值, 说明文本)的元组格式,示例:
DRF会自动把这组元组转成# 模型层或者Serializer层的choices定义示例 CONDITION_CHOICES = [ ("used", "for used items"), ("new", "for new items"), ("like new", "brand new items"), ]{值: 说明}的映射存在ChoiceField的choices属性里,供schema生成时调用。 - 第二步:自定义AutoSchema类,重写ChoiceField的schema生成逻辑
在你的项目里新建一个工具文件,比如schemas.py,写入以下代码:from rest_framework.schemas.openapi import AutoSchema from rest_framework.fields import ChoiceField class CustomDescAutoSchema(AutoSchema): def _map_field(self, field): # 先获取字段默认生成的schema结构 default_schema = super()._map_field(field) # 仅拦截处理ChoiceField类型字段 if isinstance(field, ChoiceField) and field.choices: # 按照你需要的格式生成带说明的枚举列表 enum_list = [] for val, desc in field.choices.items(): # 跳过空值选项,空值逻辑由nullable字段控制 if val in (None, ""): continue enum_list.append({val: desc}) # 替换默认的纯值枚举列表 default_schema["enum"] = enum_list return default_schema注意:你给出的「枚举数组元素为单键值对」的格式不属于OpenAPI 3.x官方标准规范,部分Swagger、Redoc等文档工具可能无法直接渲染说明文本。如果需要兼容标准规范,可以把上面修改enum的逻辑替换为oneOf结构写法,所有主流文档工具都能原生识别:
# 标准OpenAPI兼容版枚举处理逻辑,替换上面的enum_list相关代码即可 if isinstance(field, ChoiceField) and field.choices: one_of_list = [] for val, desc in field.choices.items(): if val in (None, ""): continue one_of_list.append({ "const": val, "description": desc }) default_schema["oneOf"] = one_of_list default_schema.pop("enum", None) - 第三步:注册自定义Schema类使其生效
你可以选择全局生效或者单视图生效:- 全局生效:在项目
settings.py的REST_FRAMEWORK配置中指定默认schema类REST_FRAMEWORK = { # 你已有的其他DRF配置... "DEFAULT_SCHEMA_CLASS": "你的项目路径.schemas.CustomDescAutoSchema", } - 单视图生效:如果只需要给特定接口加这个逻辑,直接在视图类中指定schema属性即可
from rest_framework.views import APIView from 你的项目路径.schemas import CustomDescAutoSchema class GoodsListView(APIView): schema = CustomDescAutoSchema() # 视图其余逻辑...
- 全局生效:在项目
配置完成后重新生成schema,就能得到你需要的带说明的Choice字段结构。
内容的提问来源于stack exchange,提问作者Sayed Ahmad
相关产品推荐
相关产品推荐

