model config
在2.0之前,配置项在model类的class Config中编写,2.0之后,使用model_config=ConfigDict(**kwagrs)。
全局修改配置
创建自己的Model父类,所有model继承该类。
关于ConfigDict的参数见文档或者源码
from pydantic import BaseModel, ConfigDict
class Parent(BaseModel):
model_config = ConfigDict(extra='allow')
class Model(Parent):
x: str
m = Model(x='foo', y='bar')
print(m.model_dump())
#> {'x': 'foo', 'y': 'bar'}
子类和父类的model_config会合并。
别名生成
Python变量规范蛇形命名法为主,而Java,前端是驼峰命名法,数据库也推荐蛇形命名法。在Java后端中,一般将数据库查出的蛇形字段转换为驼峰命名法,Python使用蛇形命名法,但数据返回前端需要转换成驼峰命名。
from typing import Literal, Any
from pydantic import BaseModel, ConfigDict, Field
from pydantic.alias_generators import to_camel
class Voice(BaseModel):
def model_dump(
self,
*,
mode: Literal['json', 'python'] | str = 'python',
include=None,
exclude=None,
by_alias: bool = False,
exclude_unset: bool = False,
exclude_defaults: bool = False,
exclude_none: bool = False,
round_trip: bool = False,
warnings: bool = True,
) -> dict[str, Any]:
return self.__pydantic_serializer__.to_python(self, mode=mode, include=include, exclude=exclude, by_alias=True,
exclude_unset=exclude_unset, exclude_defaults=exclude_defaults,
exclude_none=True, round_trip=round_trip, warnings=warnings)
model_config = ConfigDict(populate_by_name=True, alias_generator=to_camel)
name: str = Field(alias='username')
language_code: str = Field(alias='langcode', )
voice = Voice(username='Filiz', langcode='tr-TR')
print(voice.language_code)
# > tr-TR
print(voice.model_dump())
# {'username': 'Filiz', 'langcode': 'tr-TR'}
- alias_generator指定命名转换方式。
- 默认情况下,指定alias_generator之后,输入的值也需要驼峰命名为key,populate_by_name=True表示同时支持原本属性名以及驼峰命名。
- 默认情况下,Field的alias优先级高于alias_generator,如需设置后者的优先级更高,alias_priority=1。
- 重写model_dump方法,设置alias为true。
在model_config中设置alias_generator为驼峰,populate_by_name为True,Field不设置alias,同时重写model_dump设置by_alias为True,可以满足后台蛇形命名,返回数据驼峰命名的需求。
额外的属性
对传入的多余的属性,有三种处理方法。
- ignore,忽略。
- forbid,抛出异常。
- allow,保留。
修改后再次校验
默认情况下Model只有在创建时会进行数据校验,后续的赋值不会再校验,如需要,设置validate_assignment=True每次修改后校验。
Revalidate instances
对象只有初始化时会执行校验,当作为另一个对象的属性时,不会对其属性再次进行校验,参考以下代码。
from typing import List
from pydantic import BaseModel
class User(BaseModel, revalidate_instances='never'):
hobbies: List[str]
class SubUser(User):
sins: List[str]
class Transaction(BaseModel):
user: User
my_user = User(hobbies=['reading'])
t = Transaction(user=my_user)
print(t)
#> user=User(hobbies=['reading'])
my_user.hobbies = [1]
t = Transaction(user=my_user)
print(t)
#> user=User(hobbies=[1])
my_sub_user = SubUser(hobbies=['scuba diving'], sins=['lying'])
t = Transaction(user=my_sub_user)
print(t)
#> user=SubUser(hobbies=['scuba diving'], sins=['lying'])
user实例化之后修改属性,由于没有设置validate_assignment,不会进行校验,当作为属性传入Transaction后,不会报错。
Revalidate instances的值可以是’never’和’always’。
允许非Model作为属性
arbitrary_types_allowed=True