class CustomerCreate(BaseModel):
name: str = Field(example="客户名称")
contact_person: str = Field(example="联系人姓名")
phone: str = Field(example="12345678901")
email: str = Field(example="customer@example.com")
address: str = Field(example="客户地址")
class Config:
orm_mode = True
分步解释与代码分析
1. 模型定义基础
这段代码定义了一个 Pydantic 模型 CustomerCreate
,继承自 BaseModel
,用于验证和处理客户创建请求的数据。每个字段通过 Field
添加了 example
属性,并启用了 orm_mode
配置。
2. Field(example=...)
的作用
-
核心功能:为 OpenAPI/Swagger 文档提供示例值,提升接口可读性。
-
实际效果:在 FastAPI 自动生成的文档中,示例值会直接显示在请求参数示例中。
- 代码对比:
# 原始代码写法 phone: str = Field(example="12345678901") # 等效简写(Pydantic 直接支持) phone: str # 无示例提示
- 注意事项:
-
example
仅用于文档展示,不会影响数据验证逻辑。 -
若需要设置默认值,应使用
default
参数(如phone: str = Field(default="10000000000")
)。
-
3. orm_mode = True
的作用
-
核心功能:允许 Pydantic 模型直接解析 ORM 对象(如 SQLAlchemy 模型实例),实现 ORM → Pydantic 模型的自动转换。
-
典型场景:从数据库读取 ORM 对象后,转换为 Pydantic 模型返回给客户端。
- 代码示例:
# SQLAlchemy 模型 class CustomerORM(Base): __tablename__ = "customers" id = Column(Integer, primary_key=True) name = Column(String(50)) # 其他字段... # 转换操作 db_customer = CustomerORM(name="ABC Company", ...) customer_data = CustomerCreate.from_orm(db_customer) # 需要 orm_mode=True
- 关键注意:
-
此配置对请求验证无影响:
CustomerCreate
用于创建请求时,客户端发送的是 JSON 数据而非 ORM 对象。 - 新版 Pydantic 变更:在 Pydantic v2 中,
orm_mode
更名为from_attributes
,应使用:class Config: from_attributes = True # Pydantic v2+ 语法
-
4. 潜在问题与改进建议
问题 1:不必要的 orm_mode
配置
-
当前场景:
CustomerCreate
用于创建请求的输入验证,客户端发送的是 JSON 数据,而非 ORM 对象。 -
建议:移除
orm_mode
配置,除非需要从数据库模型反向转换为此模型。
问题 2:数据验证不足
-
风险点:当前模型仅校验字段类型,未对格式做严格约束(如邮箱、电话格式)。
- 改进方案:使用 Pydantic 类型或校验器增强验证:
from pydantic import EmailStr, field_validator class CustomerCreate(BaseModel): name: str = Field(..., min_length=1, example="客户名称") # 必填字段 phone: str = Field(..., pattern=r"^\d{11}$", example="12345678901") email: EmailStr = Field(example="customer@example.com") # 自动校验邮箱格式 # 其他字段... @field_validator("name") def name_must_contain_space(cls, v): if " " not in v: raise ValueError("名称应包含空格") return v
问题 3:示例数据集中管理
-
现状:每个字段单独设置
example
导致代码冗余。 - 优化方案:通过
Config.schema_extra
统一管理示例:class CustomerCreate(BaseModel): name: str contact_person: str phone: str email: str address: str class Config: # orm_mode = True # 根据需求决定是否保留 schema_extra = { "example": { "name": "客户名称", "contact_person": "联系人姓名", "phone": "12345678901", "email": "customer@example.com", "address": "客户地址" } }
总结与最佳实践
正确用法场景
配置项 | 适用场景 |
---|---|
Field(example=...) | 需要为每个字段单独指定文档示例时使用 |
orm_mode=True | 需要从 ORM 对象(如数据库查询结果)加载数据到 Pydantic 模型时启用 |
完整改进代码
from pydantic import BaseModel, EmailStr, Field, field_validator
class CustomerCreate(BaseModel):
name: str = Field(..., min_length=1, example="客户名称")
contact_person: str = Field(..., example="联系人姓名")
phone: str = Field(..., pattern=r"^\d{11}$", example="12345678901")
email: EmailStr = Field(example="customer@example.com")
address: str = Field(..., example="客户地址")
@field_validator("phone")
def validate_phone(cls, v):
if not v.isdigit():
raise ValueError("电话号码必须全为数字")
return v
class Config:
# from_attributes = True # Pydantic v2+ 语法,按需启用
schema_extra = {
"description": "客户创建请求体",
"examples": [{
"name": "ABC 公司",
"contact_person": "张三",
"phone": "13800138000",
"email": "abc@example.com",
"address": "北京市海淀区"
}]
}
关键决策点
-
是否需要 ORM 兼容:仅在需要从数据库模型转换时启用
from_attributes
。 -
数据安全:避免在请求模型中包含敏感字段(如密码),应使用专用模型。
-
文档友好性:统一示例提高可维护性,优先使用
Config.schema_extra
管理复杂示例。