前言
- 前面文章写的这么多路径函数最终 return 的都是自定义结构的字典
- FastAPI 提供了 response_model 参数,声明 return 响应体的模型
什么是路径操作、路径函数
# 路径操作
@app.post("/items/", response_model=Item)
# 路径函数
async def create_item(item: Item):
...
重点
response_model 是路径操作的参数,并不是路径函数的参数哦
- @app.get()
- @app.post()
- @app.put()
- @app.delete()
最简单的栗子
#!usr/bin/env python # -*- coding:utf-8 _*- """ # author: 小菠萝测试笔记 # blog: https://www.cnblogs.com/poloyy/ # time: 2021/9/21 5:12 下午 # file: 17_response_model.py """ from typing import List, Optional import uvicorn from fastapi import FastAPI from pydantic import BaseModel app = FastAPI() class Item(BaseModel): name: str description: Optional[str] = None price: float tax: Optional[float] = None tags: List[str] = [] @app.post("/items/", response_model=Item) async def create_item(item: Item): return item if __name__ == "__main__": uvicorn.run(app="16_Header:app", host="127.0.0.1", port=8080, reload=True, debug=True)
上面代码栗子,请求模型和响应模型都是同一个 Pydantic Model
FastAPI 通过 response_model 会做
- 将输出数据转换为 Model 中声明的类型
- 验证数据
- 在 OpenAPI 给 Response 添加 JSON Schema 和 Example Value
- 最重要:将输出数据限制为 model 的数据
正确传参的请求结果
查看 Swagger API 文档
为什么 response_model 不是路径函数参数而是路径操作参数呢?
- 因为路径函数的返回值并不是固定的,可能是 dict、数据库对象,或其他模型
- 但是使用响应模型可以对响应数据进行字段限制和序列化
区分请求模型和响应模型的栗子
需求
- 假设一个注册功能
- 输入账号、密码、昵称、邮箱,注册成功后返回个人信息
- 正常情况下不应该返回密码,所以请求体和响应体肯定是不一样的
实际代码
from typing import Optional from fastapi import FastAPI from pydantic import BaseModel, EmailStr app = FastAPI() class UserIn(BaseModel): username: str password: str email: EmailStr full_name: Optional[str] = None class UserOut(BaseModel): username: str email: EmailStr full_name: Optional[str] = None @app.post("/user/", response_model=UserOut) async def create_user(user: UserIn): return user
- 即使请求数据包含了密码,但因为响应模型不包含 password,所以最终返回的响应数据也不会包含 password
- FastAPI 通过 Pydantic 过滤掉所有未在响应模型中声明的数据