今日目标:API 的安全性始于”入口安检”。今天我们将深入学习 Pydantic,它是 FastAPI 的心脏。学会定义数据模型,让 API 能够自动拒绝那些缺字段、格式错误或类型不对的”脏数据”。今天不只是写代码,而是要彻底理解 “为什么需要数据验证”、“Pydantic 如何自动验证数据” 以及 “如何设计合理的 Schema”。
学习内容 (30 mins)
在开始写代码前,先搞懂这些核心概念,否则后面的代码你会看得云里雾里。为什么需要 Pydantic?(15 mins)
为什么需要 Pydantic?(15 mins)
什么是 Pydantic?Pydantic 是一个数据验证库,使用 Python 类型提示来验证数据。它是 FastAPI 的核心依赖,负责验证请求和响应数据。为什么需要数据验证?Pydantic 方式(FastAPI):Pydantic 的优势:
- 安全性:防止恶意数据注入
- 数据完整性:确保数据格式正确
- 开发效率:自动验证,减少手动检查代码
- 文档生成:自动生成 API 文档
- 声明式:定义模型即可,无需写验证逻辑
- 自动转换:自动将字符串转换为整数、日期等
- 详细错误:提供详细的验证错误信息
- 类型安全:基于 Python 类型提示,IDE 支持好
Pydantic 核心概念 (15 mins)
Pydantic 核心概念 (15 mins)
Schema(模式)Schema 是数据的”说明书”,定义了数据的结构和验证规则。
- 定义方式:继承
pydantic.BaseModel - 字段类型:使用 Python 类型提示(str、int、float、bool 等)
- 验证规则:使用
Field()定义更细的规则
Field() 用于给字段添加验证规则和元数据。...:表示必填字段(Ellipsis)min_length:字符串最小长度max_length:字符串最大长度gt:大于(greater than)lt:小于(less than)ge:大于等于(greater or equal)le:小于等于(less or equal)description:字段描述(会显示在 Swagger 文档中)
- 请求模型(Request Model):定义前端发送的数据结构
- 通常包含所有字段,包括密码等敏感信息
- 示例:
UserCreate(创建用户时的数据)
- 响应模型(Response Model):定义返回给前端的数据结构
- 通常不包含敏感信息(如密码)
- 使用
response_model=UserResponse自动过滤字段 - 示例:
UserResponse(返回用户信息,不含密码)
EmailStr:自动验证邮箱格式(需要安装email-validator)IPvAnyAddress:验证 IP 地址格式HttpUrl:验证 URL 格式datetime:自动解析日期时间字符串
代码任务 (90 mins)
任务 A:定义严格的用户模型
新建 代码解释:
schemas.py 文件,定义数据模型。任务分解:- 定义请求模型(UserCreate)- 用于创建用户
- 定义响应模型(UserResponse)- 用于返回用户信息
- 使用 Field 添加验证规则
Field(...):...表示必填字段Field(None, ...):None是默认值,表示可选字段min_length:字符串最小长度验证gt、lt:数值范围验证EmailStr:自动验证邮箱格式Optional[int]:可选字段,类型为 int 或 None
- 检查文件语法是否正确
- 尝试导入:
python -c "from schemas import UserCreate, UserResponse; print('OK')"
任务 B:集成到 API 路由
修改 代码解释:验证步骤:
16_main.py,使用刚才定义的模型。user: UserCreate:FastAPI 自动验证请求体response_model=UserResponse:自动过滤响应中的字段status_code=201:创建成功返回 201(Created)HTTPException:抛出 HTTP 异常,FastAPI 自动转换为错误响应
- 访问
http://localhost:8000/docs打开 Swagger UI - 测试创建用户接口:
- 点击
POST /users/ - 点击 “Try it out”
- 输入正确的数据,执行,应该返回 201
- 输入错误的数据(如密码太短),执行,应该返回 422 错误
- 点击
- 验证响应模型:
- 创建用户后,查看返回的数据
- 确认返回的数据中不包含
password字段
任务 C:测试数据验证
使用 Swagger UI 测试各种错误情况,观察 FastAPI 如何自动验证。测试用例:
- 密码太短:
- 预期:422 Error,错误信息:
ensure this value has at least 8 characters
- 预期:422 Error,错误信息:
- 邮箱格式错误:
- 预期:422 Error,错误信息:
value is not a valid email address
- 预期:422 Error,错误信息:
- 年龄越界:
- 预期:422 Error,错误信息:
ensure this value is less than 120
- 预期:422 Error,错误信息:
- 缺少必填字段:
- 预期:422 Error,错误信息:
field required(password 和 email)
- 预期:422 Error,错误信息:
- 正确的数据:
- 预期:201 Created,返回用户信息(不含密码)
拓展任务 (30 mins)
挑战 1:自定义验证器
任务:使用
@validator 装饰器添加自定义验证逻辑。例如:验证用户名不能包含特殊字符。提示:挑战 2:嵌套模型
任务:创建一个包含嵌套模型的 Schema。例如:用户模型包含地址信息(地址也是一个模型)。提示:
今日产出物
schemas.py- Pydantic 数据模型定义16_main.py- 使用 Pydantic 的 FastAPI 应用
参考代码
查看参考代码
在 GitHub 查看完整的示例代码
在线运行
使用在线编辑器测试代码
实际应用场景
Pydantic 在 API 开发中的应用
- 请求验证:自动验证前端发送的数据格式
- 响应过滤:自动过滤敏感字段(如密码)
- 类型转换:自动将字符串转换为整数、日期等
- 文档生成:自动生成 API 文档,显示字段说明
- 数据序列化:自动将 Python 对象转换为 JSON
Schema 设计最佳实践
- 分离请求和响应模型:请求模型包含所有字段,响应模型排除敏感字段
- 使用 Field 添加规则:利用 min_length、gt、lt 等规则增强验证
- 提供默认值:为可选字段设置合理的默认值
- 添加描述:使用 description 参数,便于生成文档
- 使用特殊类型:EmailStr、IPvAnyAddress 等,减少手动验证代码
上一天: 快速入门
Day 15 | FastAPI 快速入门
下一天: 依赖注入
Day 17 | 依赖注入与中间件