Pydantic未应用默认值:空字符串触发字面量验证失败问题
问题分析与解决方案
问题根源
- 默认值生效范围:你设置的默认值
"disabled"仅在字段未被显式提供时生效,如果传入空字符串"",属于有输入值的情况,默认值不会触发。 - 验证执行顺序:Pydantic会优先执行Literal类型的合法性校验,再运行自定义验证器。空字符串不符合
ENABLED_DISABLED的字面量约束,因此直接抛出literal_error,自定义验证器根本没机会执行。
解决方案
要让空字符串自动转换为默认值并通过验证,需要在Literal校验之前处理空字符串,具体实现分两种Pydantic版本:
针对Pydantic v1
给自定义验证器添加pre=True参数,让它在类型校验前执行:
from pydantic import BaseModel, Field, validator from typing_extensions import Annotated, Literal ENABLED_DISABLED = Literal["disabled", "enabled"] class GlobalSchema(BaseModel): location: Annotated[ENABLED_DISABLED, Field(description="Location")] = "disabled" @validator('location', pre=True) def handle_empty_location(cls, value): # 将空字符串转换为合法默认值 if value == '': return 'disabled' return value
针对Pydantic v2
推荐使用field_validator并设置mode='before',实现前置处理:
from pydantic import BaseModel, Field, field_validator from typing_extensions import Annotated, Literal ENABLED_DISABLED = Literal["disabled", "enabled"] class GlobalSchema(BaseModel): location: Annotated[ENABLED_DISABLED, Field(description="Location")] = "disabled" @field_validator('location', mode='before') def handle_empty_location(cls, value): if value == '': return 'disabled' return value
效果说明
当传入空字符串时,前置验证器会先将其转换为"disabled",之后Literal校验会识别到合法值,验证通过;未传入该字段时,依然会使用默认值"disabled"。
内容的提问来源于stack exchange,提问作者user2236794
相关产品推荐
相关产品推荐

