这是我参与11月更文挑战的第27天,活动详情查看:2021最后一次更文挑战。
上篇文章我们了解到,在 FastAPI 中我们可以定义数据模型类设置请求体参数,同样,FastAPI 也支持在定义路由时,使用response_model
参数指定该路由的响应模型,而且,response_model
接收的类型也是继承自 Pydantic 模块 BaseModel 类的数据模型类,语法结构完全相同。
使用响应模型
先定义一个响应模型类 User,如下:
class User(BaseModel):
name: str
password: str = '123456'
sex: str = 'male'
age: int
mobile: str
description: str = None
复制代码
定义好响应模型类之后,在定义路由时,装饰器函数中设置response_model
参数,如下:
@app.post("/add", response_model=User)
async def add(user: User):
return user
复制代码
运行代码,当收到客户端发来的请求后,根据用户的请求,FastAPI 会自动校验响应数据,然后返回指定类型的数据信息,如果返回数据的类型不是response_model
参数指定的模型,就会报错。
返回模型类指定属性
如果有一个 Pydantic 模型类,在不同的地方都有使用,因为每个地方需求不同,返回的数据也会有些不一致,比如上面的接口不返回 User 类的password
属性,可以使用response_model_include
和response_model_exclude
参数来处理。
其中,response_model_include
的作用是返回响应模型中指定的属性;response_model_exclude
的作用是排除响应模型中属性,返回其他属性。
例如下面代码,通过response_model_include
指定了返回 User 模型类的 name、sex、age 三个属性,其他属性将不再返回。
@app.post("/add", response_model=User, response_model_include=["name", "sex", "age"])
async def add(user: User):
return user
复制代码
定义基类模型
在实际开发过程中,当定义的多个响应模型存在重复的属性时,我们就可以定义一个基类模型,包含这些响应模型类重复的属性,然后我们就可以创建继承自该基类模型的子类,并各自进行扩展属性即可。
class UserBase(BaseModel):
name: str
sex: str = 'male'
age: int
mobile: str
description: str = None
class UserReq(UserBase):
password: str = "123456"
class UserRes(UserBase):
create_time: str
@app.post("/add", response_model=UserRes)
async def add(user: UserReq):
user_dict = user.dict()
user_dict["create_time"] = str(datetime.datetime.now())
res = UserRes(**user_dict)
return res
复制代码
其中,Pydantic 模型拥有
.dict()
方法,该方法会将模型数据转化为字典类型,**user_dict 相当于对该字典进行解包,然后解包的 user_dict 的键和值作为键值参数传递到 UserRes。
上述代码中,定义了一个 UserBase 用户信息基类,然后分别创建了请求体模型类 UserReq 和响应模型类 UserRes,共享了 UserBase 类的属性并各自扩展了属性,有效的减少了代码重复。
通过这篇文章,我们可以看出,FastAPI 响应模型的使用还是非常简单的,另外,在实际的项目中,模型类最好单独定义在一个文件中,便于使用和管理。
原创不易,如果小伙伴们觉得有帮助,麻烦点个赞再走呗~
最后,感谢女朋友在工作和生活中的包容、理解与支持 !