0%

FastAPI自学教程(19) - 更多模型

1. 模型分离场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
from pydantic import BaseModel, EmailStr

# 输入模型(含敏感字段)
class UserIn(BaseModel):
username: str
password: str
email: EmailStr

# 输出模型(过滤敏感字段)
class UserOut(BaseModel):
username: str
email: EmailStr

# 数据库模型(存储哈希密码)
class UserInDB(BaseModel):
username: str
hashed_password: str
email: EmailStr
  • 输入/输出分离:避免密码等敏感字段通过响应泄露
  • 职责划分:输入模型处理原始数据,数据库模型处理加密数据,输出模型控制可见字段
  • 安全警告:禁止存储明文密码,必须使用安全哈希(如bcrypt

2. 模型转换技巧

1
2
3
4
def fake_save_user(user_in: UserIn):
# 使用模型解包转换
hashed_password = "hashed_" + user_in.password
return UserInDB(**user_in.dict(), hashed_password=hashed_password)
  • .dict()方法:将Pydantic对象转为字典,支持字段过滤
  • 双星号解包UserInDB(**user_dict)实现字典到模型的快速转换
  • 增量更新:可在解包后追加新字段(如hashed_password

3. 安全哈希处理

1
2
3
4
5
6
7
8
9
10
def fake_password_hasher(raw_password: str):
return f"sec_{raw_password}_hash" # 实际应使用bcrypt等库

@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
user_in_db = UserInDB(
**user_in.dict(),
hashed_password=fake_password_hasher(user_in.password)
)
return user_in_db
  • 哈希过程应在服务端完成,客户端不参与加密逻辑
  • 推荐库:passlib + bcrypt 组合实现安全哈希
  • 响应模型自动过滤hashed_password字段,实现数据脱敏

4. 响应模型配置

1
2
3
@app.post("/user/", response_model=UserOut)
async def create_user(user_in: UserIn):
return fake_save_user(user_in)
  • response_model控制最终输出结构,与数据库模型隔离
  • 支持嵌套模型:如response_model=List[UserOut]
  • 自动文档生成:Swagger UI展示过滤后的响应结构

5. 多版本兼容性

1
2
3
4
5
6
7
8
9
# Python 3.8+ 写法
from typing import Union

class UserIn(BaseModel):
full_name: Union[str, None] = None

# Python 3.10+ 写法
class UserIn(BaseModel):
full_name: str | None = None
  • 可选字段声明:不同Python版本的类型注解差异
  • 向后兼容:推荐使用Annotated注解方式
  • 统一校验规则:不同版本保持相同的数据验证逻辑

注意事项

  1. 模型继承可复用公共字段(如创建BaseUser模型)
  2. 使用model_config配置额外字段处理策略(如extra="forbid"
  3. 通过alias_generator实现字段名自动转换
  4. 生产环境应使用真正的密码哈希算法(如Argon2)