参考链接:Pydantic官方文档
文章目录
- 定义数据模型
- 创建模型实例
- 数据验证
- 数据转换
- 模型转换
- 模型更新
- 模型配置
- 辅助类
- Field
- @validator
Pydantic
是一个 Python 库,主要用于数据验证和管理。数据验证是指检查数据是否符合预定的规则和格式,比如检查数据类型是否正确,是否缺少必要的字段等。数据管理是指定义数据的结构和行为,比如设置默认值,转换数据类型等。
以下是 Pydantic 的一些基本操作语法:
定义数据模型
首先,通过继承 Pydantic 提供的 BaseModel
类定义一个数据模型:
from pydantic import BaseModel
class User(BaseModel):
id: int
name: str
email: str
is_active: bool = True
在这个例子中,定义了 User
数据模型,有四个字段:id
(整数类型)、name
(字符串类型)、email
(字符串类型)和 is_active
(布尔类型,默认值为 True
)。
创建模型实例
创建数据模型的实例非常简单,只需要按照定义的字段传递相应的值即可:
user = User(id=1, name="John Doe", email="john.doe@example.com")
如果某个字段有默认值,你可以选择不提供它:
user = User(id=1, name="John Doe", email="john.doe@example.com") # is_active 将默认为 True
数据验证
当创建模型实例时,Pydantic 会自动进行数据验证。如果数据不符合定义的类型,会进行报错:
try:
user = User(id="not_an_integer", name="John Doe", email="john.doe@example.com")
except ValidationError as e:
print(str(e)) # 输出错误信息
数据转换
Pydantic 可以自动进行数据类型转换。例如,如果传递一个字符串类型的 id
,Pydantic 会自动将其转换为整数类型:
user = User(id="1", name="John Doe", email="john.doe@example.com")
print(user.id) # 输出: 1
模型转换
Pydantic 可以将模型转换为字典或 JSON 格式:
user_dict = user.dict()
print(user_dict) # 输出: {'id': 1, 'name': 'John Doe', 'email': 'john.doe@example.com', 'is_active': True}
user_json = user.json()
print(user_json) # 输出: {"id": 1, "name": "John Doe", "email": "john.doe@example.com", "is_active": true}
模型更新
可以使用 update
方法来更新模型的属性:
user.update(name="Jane Doe")
print(user.name) # 输出: Jane Doe
模型配置
Pydantic 允许通过 Config
类来配置模型的行为。例如,你可以设置一个示例数据,这在生成文档时非常有用:
class User(BaseModel):
id: int
name: str
email: str
is_active: bool = True
class Config:
schema_extra = {
"example": {
"id": 1,
"name": "John Doe",
"email": "john.doe@example.com",
"is_active": True,
}
}
在这个例子中,添加了 Config
类来定义模型的元数据,比如 schema_extra
,可以用于生成文档或提供示例数据。
辅助类
Field
导入
from pydantic import BaseModel, Field
字段别名
使用 alias 参数可以为字段设置别名,这在处理 JSON 数据时非常有用,因为 JSON 字段名通常与 >Python 字段名不同:
class User(BaseModel):
id: int = Field(alias="_id")
name: str
email: str = Field(alias="email_address")
is_active: bool = Field(default=True)
在这个例子中,id 字段在 JSON 数据中的别名是 _id
,而 email 字段的别名是 email_address
。
字段描述
使用 description 参数可以为字段添加描述信息,这在生成文档时非常有用:
class User(BaseModel):
id: int = Field(description="The unique identifier of the user")
name: str = Field(description="The full name of the user")
email: str = Field(description="The user's email address")
is_active: bool = Field(default=True, description="Whether the user is active or not")
字段标题
使用 title 参数可以为字段设置标题,这在生成文档时非常有用:
class User(BaseModel):
id: int = Field(title="The ID of the user")
name: str = Field(title="The Name of the user")
email: str = Field(title="The Email of the user")
is_active: bool = Field(default=True, title="The Active Status of the user")
字段示例
使用 example 参数可以为字段设置示例值,这在生成文档或测试时非常有用:
class User(BaseModel):
id: int = Field(example=123)
name: str = Field(example="John Doe")
email: str = Field(example="john.doe@example.com")
is_active: bool = Field(default=True, example=True)
字段默认值
Field 的 default 参数可以设置字段的默认值:
class User(BaseModel):
id: int
name: str
email: str
is_active: bool = Field(default=True)
在这个例子中,is_active 字段有一个默认值 True。
字段常量
Field 的 const 参数可以设置字段为常量,这意味着该字段的值在实例化后不能被修改:
class User(BaseModel):
id: int
name: str
email: str
is_active: bool = Field(default=True, const=True)
在这个例子中,is_active 字段被设置为常量,它的值在实例化后不能被修改。
字段验证
Field 的 regex 参数可以设置字段的正则表达式验证:
class User(BaseModel):
id: int
name: str
email: str = Field(regex=r"^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$")
is_active: bool = Field(default=True)
在这个例子中,email 字段的值必须匹配指定的正则表达式,否则会抛出验证错误。
在 Pydantic 中,@validator
是用于创建自定义验证方法的装饰器。这些自定义验证方法可以用于对模型字段的值进行复杂的验证逻辑,或者在某些情况下对多个字段的值进行交叉验证。
以下是 @validator
的一些应用场景:
@validator
首先,需要从 pydantic
模块中导入 validator
:
from pydantic import BaseModel, validator
单字段验证
@validator
可以用于对单个字段的值进行验证。例如,可以确保一个字段的值在某个范围内:
class User(BaseModel):
age: int
@validator('age')
def age_must_be_between_18_and_100(cls, v):
if v < 18 or v > 100:
raise ValueError('Age must be between 18 and 100')
return v
在这个例子中,age_must_be_between_18_and_100
方法是一个验证器,检查 age
字段的值是否在 18 到 100 之间。如果值不在范围内,会抛出一个 ValueError
。
多字段验证
@validator
也可以用于对多个字段的值进行交叉验证。例如,可以确保两个字段的值满足某个条件:
class User(BaseModel):
name: str
password: str
password_confirm: str
@validator('password_confirm')
def passwords_match(cls, v, values):
if 'password' in values and v != values['password']:
raise ValueError('Passwords do not match')
return v
在这个例子中,passwords_match
方法是一个验证器,检查 password_confirm
字段的值是否与 password
字段的值相匹配。如果不匹配,会抛出一个 ValueError
。values
参数是一个字典,包含了所有其他字段的值。
验证器模式
@validator
还可以用于设置验证器的模式。模式可以是pre
或
each_item
,分别对应于在验证开始之前和列表中的每个项之前执行验证器。
class User(BaseModel):
name: str
items: List[str]
@validator('items', pre=True)
def split_items(cls, v):
if isinstance(v, str):
return v.split(',')
return v
在这个例子中,split_items
方法是一个 pre
模式的验证器,检查 items
字段的值是否是一个字符串,如果是,则将其分割成一个列表。
验证器别名
@validator
可以通过设置allow_reuse=True
来创建别名,这样可以对同一个验证逻辑使用不同的字段名。
class User(BaseModel):
name: str
password: str
password_confirm: str
@validator('password_confirm', allow_reuse=True)
@validator('password', allow_reuse=True)
def password_length(cls, v):
if len(v) < 8:
raise ValueError('Password must be at least 8 characters long')
return v
在这个例子中,password_length
方法被设置为两个字段的验证器,它检查这两个字段的值的长度是否至少为 8。