我有一个带有 pydantic 的嵌套对象的小例子。
from typing import Dict
from pydantic import BaseModel, Field, ValidationError
class UserType(BaseModel):
name: str = Field(min_length=1)
type: str = Field(min_length=1)
class AppConfig(BaseModel):
key1: int = Field(gt=0)
objects: Dict[str, UserType]
try:
data = {
"key1": 1,
"objects": {
"type1": {
"name": "Name 2",
},
"type2": {
"name": "Name 1"
}
}
}
c = AppConfig(**data)
print(c.model_dump_json())
except ValidationError as e:
print(e)
这显然失败了,因为
type
未在 UserType
模型中设置。我的目标是在实际验证之前使用 UserType.type
字典中的关联键以某种方式设置每个 objects
。比如:
type = key
内部数据,然后传递给 UserType 模型这可以通过
pydantic
以某种方式实现吗?
我知道我可以在将数据传递到主模型之前完成所有这些操作,但我想知道这在
pydantic
模型中是否可行。
我也尝试过使用这样的
model_post_init()
方法:
from typing import Dict
from pydantic import BaseModel, Field, ValidationError
class UserType(BaseModel):
name: str = Field(min_length=1)
type: str = Field(min_length=1)
class AppConfig(BaseModel):
key1: int = Field(gt=0)
objects: Dict[str, UserType]
def model_post_init(self, __context) -> None:
values = self.dict()
for obj_type, obj in values["objects"].items():
print(obj, obj_type)
obj["type"] = obj_type
try:
data = {
"key1": 1,
"objects": {
"type1": {
"name": "Name 2",
#"type": "t"
},
"type2": {
"name": "Name 1",
#"type": "t"
}
}
}
c = AppConfig(**data)
print(c.model_dump_json())
except ValidationError as e:
print(e)
但是这个方法是在验证之后执行的,并且之前验证失败了。还尝试在数据负载中设置一些虚拟类型值,然后在
model_post_init()
中覆盖它,但这根本不起作用,模型只有类型的原始虚拟值。
您可以在验证之前使用
field_validator
和 mode=before
字段更新对象数据:objects