Pydantic的API和签名介绍

很好 👍
现在我们就系统地、工程化地把 Pydantic v2 的 API 过一遍。

不会讲入门教程式内容,而是:

常用 API + 使用场景 + 签名结构 + 架构定位

全部基于 Pydantic v2



一、BaseModel 基础结构

from pydantic import BaseModel

class User(BaseModel):
    id: int
    name: str

核心能力:

  • 类型校验
  • 自动转换
  • 序列化
  • 错误信息结构化


二、字段定义(Field)

签名(核心参数):

Field(
    default=...,
    default_factory=...,
    alias=...,
    title=...,
    description=...,
    gt=..., ge=..., lt=..., le=...,
    min_length=..., max_length=...,
    pattern=...,
    strict=...,
)

示例:

from pydantic import Field

class ItemDTO(BaseModel):
    price: float = Field(gt=0)
    name: str = Field(min_length=1, max_length=100)

用途:

  • 基础约束
  • OpenAPI 描述
  • alias 处理


三、字段校验器(field_validator)

签名:

@field_validator(
    field_name,
    mode="before" | "after"
)

示例:

from pydantic import field_validator

class ItemDTO(BaseModel):
    price: float

    @field_validator("price")
    @classmethod
    def check_price(cls, v):
        if v <= 0:
            raise ValueError("must be positive")
        return v

mode 参数

  • before → 原始输入值
  • after → 类型转换之后


四、模型级校验(model_validator)

签名:

@model_validator(mode="before" | "after")

示例:

from pydantic import model_validator

class OrderDTO(BaseModel):
    start: int
    end: int

    @model_validator(mode="after")
    def check_range(self):
        if self.start >= self.end:
            raise ValueError("start must < end")
        return self

用途:

  • 跨字段校验
  • 复杂结构校验


五、computed_field

签名:

from pydantic import computed_field

示例:

class UserDTO(BaseModel):
    first_name: str
    last_name: str

    @computed_field
    @property
    def full_name(self) -> str:
        return f"{self.first_name} {self.last_name}"

特点:

  • 参与序列化
  • 只读
  • 不参与输入校验


六、model_dump(序列化)

model.model_dump()
model.model_dump_json()

参数常见:

model_dump(
    exclude_none=True,
    by_alias=True,
)

示例:

user.model_dump(exclude_none=True)


七、model_validate(反序列化)

User.model_validate(data)

等价于:

User(**data)

但推荐用 model_validate。



八、配置(model_config)

v2 使用:

from pydantic import ConfigDict

class User(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
        frozen=True,
        str_strip_whitespace=True,
    )

常用配置:

参数作用
extra="forbid"禁止多余字段
frozen=True只读模型
strict=True严格模式
from_attributes=True支持 ORM


九、Strict 模式

默认:

id: int

允许:

"id": "1"

被转换为 int。

如果你想禁止自动转换:

from pydantic import StrictInt

id: StrictInt

或者:

model_config = ConfigDict(strict=True)


十、自定义类型(高级)

你可以定义:

from pydantic import GetCoreSchemaHandler
from pydantic_core import core_schema

但这是进阶用法。

通常你只需要:

from typing import Annotated
from pydantic import Field

price: Annotated[float, Field(gt=0)]


十一、泛型模型

from typing import Generic, TypeVar
from pydantic import BaseModel

T = TypeVar("T")

class Response(BaseModel, Generic[T]):
    data: T


十二、BaseSettings(配置管理)

from pydantic_settings import BaseSettings

class Settings(BaseSettings):
    db_url: str

自动从环境变量读取。



十三、Pydantic Dataclass

from pydantic.dataclasses import dataclass

但在 DDD 中:

不建议领域层用这个。



十四、重要原则总结

需求用什么
单字段校验field_validator
跨字段校验model_validator
输出计算字段computed_field
严格类型StrictInt
禁止多余字段extra="forbid"
ORM 转换from_attributes=True
JSON 输出model_dump


十五、你现在应该怎么练?

不要盲目记 API。

建议练习顺序:

  1. DTO 基础校验
  2. 跨字段校验
  3. 严格模式
  4. 序列化控制
  5. DTO → 领域转换


🎯 现在我给你一个实战题

实现一个:

CreateUserDTO:

  • username: 3~20 字符
  • password: 至少 8 位
  • email: 合法邮箱
  • password_confirm 必须等于 password
  • 禁止多余字段
  • 输出时不返回 password

写出完整 pydantic v2 版本。

这题会覆盖 80% 常用 API。

文章标签:

评论(0)