大家好,我是村长~~ 今日 fastApi 干货来了,文末还有书籍赠送噢~~
在 fastApi
中可以定义请求体body
模型,关于这部分内容可以查看之前的文章 同样的,fastApi
支持在定义路径操作的时候,使用response_model
参数指明该路径的响应模型
其具有以下特点:
- 转换为类型声明的输出数据
- 响应数据的校验
- 在 OpenAPI 路径操作中,为响应添加 JSON Schema
- 生成 API 文档
其中,个人觉得最重要的一点是:把输出的数据字段限制在该模型以内!
而且,response_model
接收的类型与声明 Pydantic
模型属性的类型,语法完全相同
使用响应模型
先来看下简单的用法,定义一个响应模型 User
from pydantic import BaseModel, EmailStr class User(BaseModel): name: str sex: str = "male" age: int email: EmailStr phone: str
定义完模型之后,在路径操作装饰器函数中设置 response_model
参数,代码如下:
from fastapi import FastAPI app = FastAPI() @app.post("/user/", response_model=User) async def create_user(user: User): return user
运行代码,当收到客户端发来的请求后,根据用户的请求,返回对应用户的信息
响应模型参数
细心的朋友应该发现了,上面定义的 User
模型中,sex
是默认参数
但是有时候我们不需要返回未修改的或者为默认值的字段
例如,NoSQL 数据库的模型中往往包含很多可选属性,如果输出含默认值的属性,输出的 JSON 响应会特别长,此时,可以省略只含默认值的属性。
response_model_include
如果只有一个 Pydantic
模型, 但是在不同的接口中,因为某些需求不同,返回的 body
又不一样。
那么可以使用这种快捷方法来处理
在路径操作装饰器参数还有 response_model_include
和 response_model_exclude
其中,response_model_include
的作用是返回集合中指定(忽略其它属性)的属性内容
response_model_exclude
的作用是排除该集合中的其他字段属性(包含其它属性)
items = { "bar": {"name": "Foo", "age": 25, "email": "xxx@qq.com", "phone": 123456}, } @app.get( "/items/{name_id}/name", response_model=User, response_model_exclude_unset=True, response_model_include=['name', 'phone'] ) async def read_item_name(name_id: str): return items[name_id]
这两个参数的值是都是由属性名 str
组成的 set
response_model_exclude_unset
在路径参数装饰器函数中,将 response_model_exclude_unset
设置为 True
响应中就不会再包含未修改过默认值的属性,而是只包含修改过值的字段
items = { "bar": {"name": "Foo", "age": 25, "email": "xxx@qq.com", "phone": 123456}, } @app.get( "/items/{name_id}/name", response_model=User, response_model_exclude_unset=True ) async def read_item_name(name_id: str): return items[name_id]
可以看到, response_model_exclude_unset
参数为 True
的时候,未修改的默认参数不会返回
反之,给默认值字段赋予了新的内容,则新的值会包含在返回的响应中 !
还有一种情况是: 赋的新值与默认值相同
例如下面 id
为 baz
的商品,
class Item(BaseModel): name: str description: Optional[str] = None price: float tax: float = 10.5 tags: List[str] = [] items = { "foo": {"name": "Foo", "price": 50.2}, "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2}, "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []}, } @app.get( "/items/{name_id}/name", response_model=Item, response_model_exclude_unset=True ) async def read_item_name(name_id: str): return items[name_id]
返回结果如下:
虽然 FastAPI
能够识别出 description、tax 和 tags
的值与默认值相同,这些值也会显式设置(而不是取自默认值)