Pydantic未应用默认值
我有一个这样的数据结构。如果我在'location'里输入“启用”或“禁用”,那么这个功能就能正常工作,验证也没问题。如果我输入一个随机字符串,它就会失败(这也是应该的)。问题是,如果'location'是一个空字符串,这个验证也会失败。我希望它能设置一个默认值,并且通过验证。我尝试添加下面的验证函数,但根本没有进入这个函数。它自动就失败了。
Input should be 'disabled' or 'enabled' [type=literal_error, input_value='', input_type=str]"
我已经添加了默认值,但它还是失败了。你觉得我漏掉了什么吗?
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')
# def validate_location(cls, value):
# if value not in ENABLED_DISABLED:
# raise ValueError(f'Invalid value for location. Must be one of: {", ".join(ENABLED_DISABLED)}')
# return value or "disabled"
2 个回答
1
为了让你能够传递任何值,你应该把 ENABLED_DISABLED
替换成 str
。你之所以无法调试,是因为你需要像这样传递位置的值:a = GlobalSchema(location="")
。这是因为当你没有指定确切的字段时,验证函数会返回一个额外的值。最后,当值不在你预定义的列表中时,你不应该抛出异常。所以你可以得到类似这样的代码:
from pydantic import BaseModel, Field, field_validator
from typing_extensions import Annotated, Literal
ENABLED_DISABLED = Literal["disabled", "enabled"]
class GlobalSchema(BaseModel):
location: Annotated[str, Field(description="Location")] = "disabled"
@field_validator('location')
def validate_location(cls, value):
return "enabled" if value == "enabled" else "disabled"
print(GlobalSchema(location=""))
1
我觉得可以通过使用一个 pre
或 before
验证器来实现想要的效果。这个验证器会在 Pydantic 进行内部验证之前被调用,所以不需要重新实现对字面值的验证。我的建议解决方案大概是这样的:
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 validate_location(cls, value):
if value == "":
return cls.model_fields["location"].default
return value
print(GlobalSchema(location=""))
这段代码会输出:
location='disabled'
如果值不正确,它会抛出:
ValidationError: 1 validation error for GlobalSchema
location
Input should be 'disabled' or 'enabled' [type=literal_error, input_value='foo', input_type=str]
For further information visit https://errors.pydantic.dev/2.5/v/literal_error
我建议你再看看 Pydantic 文档中的验证器部分: https://docs.pydantic.dev/latest/concepts/validators/
希望这对你有帮助!