大家好~我是小方,欢迎大家关注笋货测试笔记体完记得俾个like呀
回顾
在上篇中,我们进行了项目结构的调整和权限认证中间件的开发,总的来说因为调整了项目目录结构,导致好多地方得改改,在你们看到这篇文章时,我已经调整好了代码,能 run 起来了···所以尽量不要重构代码...今天干嘛呢?大概讲一下通过请求上下文获取用户数据和新增 BaseCrud 基类、BaseBody 基类、BaseDto 基类
contextvars
- 什么是上下文
Context 你可以理解为包含了相关信息内容的对象,举个栗子,黑袍纠察队第三季开播了,但是你没看过第一二季,不了解阿祖、星光、屠夫以及之前的剧情,直接看第三季,是完全看不懂的,因为你缺失了这部剧的上下文;如果我看过前两季,我可以将前两季的剧情浓缩成一个 10min 短视频(设置上下文对象),你只需要花 10min 看这个短视频(获取上下文对象),接着继续看第三季
我们先来段 demo 体会一下
import asyncio
import contextvars
# 申明Context变量
request_id = contextvars.ContextVar('Id of request')
async def get():
# Get Value
print(f'Request ID (Inner): {request_id.get()}')
async def new_coro(req_id):
# Set Value
request_id.set(req_id)
await get()
print(f'Request ID (Outer): {request_id.get()}')
async def main():
tasks = []
for req_id in range(1, 5):
tasks.append(asyncio.create_task(new_coro(req_id)))
await asyncio.gather(*tasks)
asyncio.run(main())
contextvars 核心方法是 get 和 set,分别是获取值和设置值,上面的 demo 可以看到数据状态在协程之间互不影响,并且并发安全的
关于 contextvars 更多的知识可看掘金这个帖子,比较详细,个人能力不足,不能好好表达给大家听···
总的来说,上下文就一个堆栈,每次 set 一次对象就向堆栈增加一层数据, 每次 reset 就是 pop 掉最上层的数据, 而在 Contextvars 中, 通过 Token 对象来维护堆栈之间的交互
那contextvars在fastapi中怎么运用呢?之前用Depends
做权限认证时,每个接口都得写depends(xxxx)
获取用户数据,确实有点烦,所以这次换了中间件来实现权限认证,用户数据直接从上下文中的request获取
来看看authentication
方法,最后认证通过,将用户数据保存在request中,接着通过依赖的方式,将request保存在上下文,需要获取时,直接通过get
方法获取request中的user
注册路由时,加载了依赖
保存请求上下文方法
需要获取请求上下文时
总结:利用fastapi的depend依赖和contextvar上下文来存储当前请求对象,接着让依赖绑定在全局的api_router上,依赖做的事情就是把当前请求存到上下文中,之后在哪里都能获取到
BaseCrud 基类
大家在编写UserDao
和ProjectDao
发现,其实有好多代码都是比较重复,为此这里封装了一个BaseCrud
基类,目前只支持单表,BaseCrud
基类代码借鉴于pity项目,感谢pity项目!!!
- 查询
这里只展示核心方法,查询一条、查询全部、分页查询、过滤查询、判断是否存在、通过主键id获取数据···都是基于该核心方法
这里的过滤条件,其实就是通过**kwargs
进行接收,形式为xx = xx
,而filter_list
就是为了一些特殊的过滤条件设置的,这里最终的结果是返回一个列表,列表形式为[xx == xx, xx == xx···]
- 更新
通过主键id更新,跟之前的封装方法差不多一致,通过传入model,循环setattr
值
批量更新,先通过filter_list
过滤查询数据,再通过传递进来的kwargs
进行批量更新
- 删除
这里通过主键id进行删除数据,跟之前封装的方法差不多一致
- 新增
通过实例化表模型,再将实例化的对象加入到session
中进行提交,提交成功后相当于在表中插入一条数据
- 如何使用
xxDao
直接继承BaseCrud
,接着设置model
类变量,最后通过cls.xxxx
使用
- BaseDto 返参基础模型
这里的每个返参dto都继承这个BaseDto,需要配置项,直接在Config
加上即可
例如搜索用户信息接口的返参dto
- BaseBody 入参基础模型
这里的每个入参body都继承这个BaseBody,BaseBody里面配置着错误模板,我们可以来看看
这里结合请求参数校验异常处理器,算是很完美的返回错误信息,以前返回的英文报错有点难看了···
- 其他小优化
表结构改动、启动时创建表等,大家可看看具体的提交记录
总结
到目前为止,我们已经完成了项目的重构和调整,调整起来还是挺费时间的,大家拉最新的代码look look吧,下篇我们来进行项目同步逻辑的设计
- 项目地址