Pydantic是python用来做数据校验的非常好用的工具,让我们来一步一步慢慢深入吧。

1 基础使用

主要在于如何继承Pydantic中的BaseModel对类中的数据进行数据校验。

1.1 数据项缺失

from pydantic import BaseModel
from typing import List


class User(BaseModel):
    id: int
    age: int
    name: str
    friends: List[str]


user = User(id=1, age=18, name="john")

# pydantic_core._pydantic_core.ValidationError: 1 validation error for User
# friends
#   Field required [type=missing, input_value={'id': 1, 'age': 18, 'name': 'john'}, input_type=dict]

1.2 数据类型不匹配

from pydantic import BaseModel
from typing import List


class User(BaseModel):
    id: int
    age: int
    name: str
    friends: List[str]


user = User(id=1, age=18, name="john", friends=["mary", 1])

# pydantic_core._pydantic_core.ValidationError: 1 validation error for User
# friends.1
#   Input should be a valid string [type=string_type, input_value=1, input_type=int]

1.3 数据验证通过

from pydantic import BaseModel
from typing import List


class User(BaseModel):
    id: int
    age: int
    name: str
    friends: List[str]


user = User(id=1, age=18, name="john", friends=["mary", "tom"])
print(user) # class
print(user.model_dump()) # dict
print(user.model_dump_json()) # json

# id=1 age=18 name='john' friends=['mary', 'tom']
# {'id': 1, 'age': 18, 'name': 'john', 'friends': ['mary', 'tom']}
# {"id":1,"age":18,"name":"john","friends":["mary","tom"]}

2 数据验证

基础数据类型:int, str 枚举类型:Literal 注释数据类型:Annotated + 大小判断
from pydantic import BaseModel
from typing import List, Literal
from typing_extensions import Annotated
from annotated_types import Gt


class User(BaseModel):
    id: Annotated[int, "id需要大于1", Gt(1)]
    age: int
    name: str
    color: Literal["green", "red"]
    friends: List[str]


user = User(id=2, age=18, name="john", color="red", friends=["mary", "tom"])
print(user)

3 多个类联合使用

某一个校验类可以当做其他校验类的内容来使用
from pydantic import BaseModel
from typing import List, Literal
from typing_extensions import Annotated
from annotated_types import Gt


class User(BaseModel):
    id: Annotated[int, "id需要大于1", Gt(1)]
    age: int
    name: str
    color: Literal["green", "red"]
    friends: List[str]


class Address(BaseModel):
    zip: str
    city: str
    phone: str


class Room(BaseModel):
    student: User
    address: Address


user = User(id=2, age=18, name="tom", color="red", friends=["john"])
address = Address(zip="xx", city="beijing", phone="124")
room = Room(student=user, address=address)
print(room)

4 Fields详细使用

4.1 Fields默认设置

默认设置有两种,一种是使用Fields原生进行设置,另一种借助Annotated注释数据类型结合Fiedls函数进行设置。
from pydantic import BaseModel, Field
from typing import List, Literal
from typing_extensions import Annotated
from annotated_types import Gt
from uuid import uuid4


class User(BaseModel):
    id: Annotated[int, "id需要大于1", Gt(1)]
    age: int = Field(gt=0, lt=100, default=18)
    name: Annotated[str, Field(default_factory=lambda: uuid4().hex)]
    color: Literal["green", "red"]
    friends: List[str]


user = User(id=2, color="red", friends=["john"])
print(user)

# id=2 age=18 name='f6ba920c437b4d74b266bc5b0f1c285e' color='red' friends=['john']

4.2 Fields严格模式

一般来说,如果BaseModel中设置为int,input为str时,BaseModel会自动从str转为int,如果我们不想要这种转换,则可以设置Fields为严格模式。
from pydantic import BaseModel, Field
from typing import List, Literal
from typing_extensions import Annotated
from annotated_types import Gt
from uuid import uuid4


class User(BaseModel):
    id: Annotated[int, "id需要大于1", Gt(1)]
    age: int = Field(gt=0, lt=100, default=18, strict=True)
    name: Annotated[str, Field(default_factory=lambda: uuid4().hex, strict=True)]
    color: Literal["green", "red"]
    friends: List[str]


user = User(id=2, color="red", friends=["john"])
print(user)

# id=2 age=18 name='f6ba920c437b4d74b266bc5b0f1c285e' color='red' friends=['john']