如何创建支持CharField或字符列表的Django Serializer字段并适配DRF Spectacular
实现支持字符串或字符串列表的Serializer字段并适配DRF Spectacular
要实现同时支持单个字符串或字符串列表的Serializer字段,并且让DRF Spectacular正确生成包含两种类型的API文档,可以按以下步骤操作:
1. 自定义Serializer字段
继承DRF的Field类,重写类型校验和序列化逻辑,同时兼容两种输入类型:
from rest_framework import serializers class CharOrListCharField(serializers.Field): def __init__(self, **kwargs): # 初始化嵌套的CharField和ListField,传递所有参数(如max_length) self.char_validator = serializers.CharField(**kwargs) self.list_validator = serializers.ListField(child=serializers.CharField(**kwargs), **kwargs) super().__init__(**kwargs) def to_internal_value(self, data): # 校验输入:优先尝试列表类型,失败则尝试字符串类型 if isinstance(data, list): return self.list_validator.to_internal_value(data) try: return self.char_validator.to_internal_value(data) except serializers.ValidationError: raise serializers.ValidationError("该字段必须是字符串或字符串列表") def to_representation(self, value): # 序列化输出:保留原类型结构 if isinstance(value, list): return self.list_validator.to_representation(value) return self.char_validator.to_representation(value)
2. 适配DRF Spectacular文档生成
通过extend_schema_field装饰器,让字段生成包含两种类型的OpenAPI Schema(使用oneOf关键字):
from drf_spectacular.utils import extend_schema_field @extend_schema_field({ "oneOf": [ {"type": "string"}, {"type": "array", "items": {"type": "string"}} ] }) class CharOrListCharField(serializers.Field): # 上述自定义字段的代码
如果需要传递CharField的额外约束(如max_length)到Schema中,可以完善Schema定义:
@extend_schema_field(lambda field: { "oneOf": [ { "type": "string", "maxLength": field.char_validator.max_length if hasattr(field.char_validator, 'max_length') else None }, { "type": "array", "items": { "type": "string", "maxLength": field.char_validator.max_length if hasattr(field.char_validator, 'max_length') else None } } ] }) class CharOrListCharField(serializers.Field): # 上述自定义字段的代码
3. 在Serializer中使用字段
直接在Serializer类中声明该字段即可:
class MySerializer(serializers.Serializer): my_field = CharOrListCharField(max_length=100) # 其他字段...
这样配置后,该字段既可以接收单个字符串或字符串列表作为输入,DRF Spectacular生成的API文档也会明确标注该字段支持两种类型。
内容的提问来源于stack exchange,提问作者Slav
相关产品推荐
相关产品推荐

