FastAPI Pydantic 模型

FastAPI Pydantic v2 模型模式:字段约束、验证器、嵌套模型、响应模式和序列化配置。

1. BaseModel 基础

from pydantic import BaseModel, Field, EmailStr
from typing import Optional
from datetime import datetime
from uuid import UUID

class UserBase(BaseModel):
    email: EmailStr
    name: str = Field(..., min_length=1, max_length=100)
    age: Optional[int] = Field(None, ge=0, le=150)
    role: str = Field(default="user", pattern="^(user|admin|moderator)$")

class UserCreate(UserBase):
    password: str = Field(..., min_length=8, max_length=128)

class UserResponse(UserBase):
    id: UUID
    created_at: datetime
    is_active: bool = True
    model_config = {"from_attributes": True}

2. 字段验证器 (Pydantic v2)

from pydantic import BaseModel, field_validator, model_validator
import re

class RegisterRequest(BaseModel):
    username: str
    password: str
    confirm_password: str

    @field_validator("username")
    @classmethod
    def username_alphanumeric(cls, v: str) -> str:
        if not re.match(r"^[a-zA-Z0-9_]{3,30}$", v):
            raise ValueError("用户名必须为 3-30 位字母数字或下划线")
        return v.lower()

    @model_validator(mode="after")
    def passwords_match(self) -> "RegisterRequest":
        if self.password != self.confirm_password:
            raise ValueError("两次密码不一致")
        return self

3. 嵌套模型

from pydantic import BaseModel
from typing import List

class Address(BaseModel):
    street: str
    city: str
    country: str = "CN"

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

class Article(BaseModel):
    title: str
    content: str
    author_id: int
    tags: List[Tag] = []
    address: Optional[Address] = None

4. 响应模型与过滤

class UserPublic(BaseModel):
    id: int
    name: str
    created_at: datetime
    model_config = {"from_attributes": True}

class Page(BaseModel):
    items: List[UserPublic]
    total: int
    page: int
    size: int

@app.get("/users", response_model=Page)
async def list_users(page: int = 1, size: int = 20, db: DB = Depends(get_db)):
    total = db.query(User).count()
    users = db.query(User).offset((page-1)*size).limit(size).all()
    return Page(items=users, total=total, page=page, size=size)

5. model_config 选项

from pydantic import BaseModel, ConfigDict

class StrictModel(BaseModel):
    model_config = ConfigDict(
        str_strip_whitespace=True,
        validate_assignment=True,
        use_enum_values=True,
        from_attributes=True,
        populate_by_name=True,
        frozen=False,
    )

6. 常用字段类型

类型导入来源说明
EmailStrpydantic验证邮箱格式
HttpUrlpydantic验证 URL 格式
UUIDuuid接受字符串或 UUID
datetimedatetimeISO 8601 解析
Decimaldecimal精确数值
Literal["a","b"]typing枚举字符串