请求上下文管理(request,session)
- 请求到来会之后wsgi会触发flask类的__call__方法,由__call__方法再次调用wsgi_app方法
- 在wsgi_app方法中
- 首先将请求相关封装后的request对象+空的session封装到一个RequestContext对象空,即ctx
- 将ctx交给LocalStack对象,再由LocalStack将ctx添加到Local中,
Local结构 __storage__:{5468:{stack:[ctx,]}}
- 根据请求中的cookie中提取名为session的值,解密并反序列化,再次赋值给ctx.session
- 视图函数
- 把session中的数据再次写到session中
- 将ctx删除
- 结果返回给用户浏览器
- 断开socket连接
多app离线脚本:
from flask import current_app
app1 = create_app()
app_ctx1 = app1.app_context() # app_ctx = app/g
app2 = create_app()
app_ctx2 = app2.app_context() # app_ctx = app/g
with app_ctx1: # __enter__,通过LocalStack放入Local中
print(current_app) # app1
with app_ctx2:
print(current_app) # app2
print(current_app) # app1
map(function, iterable, ...)
func有几个参数,就有几个可迭代对象,返回值构成迭代器
# 偏函数
import functools
def index(arg):
return arg
request = functools.partial(index,"request")
print(request)
super().func() # 按照mro列表查找func
Base.func(obj) # 就按父类的func方法执行
------------------------------------------------
class Foo(object):
def __init__(self):
# self.storage = {}
object.__setattr__(self,'storage',{})
def __setattr__(self, key, value):
print(key,value,self.storage)
obj = Foo()
obj.xx = 123
# check csrf token
from flask_wtf.csrf import validate_csrf
try:
validate_csrf(form.csrf_token.data)
except ValidationError:
return redirect("/")
init
str
repr
new,单例/rest framework序列化
call,flask源码请求入口,django请求入口(WSGIHandler.__call__)。
getattr
setattr flask的Local对象
delattr,
setitem
getitem # 使得对象可以像字典一样操作
delitem
iter # form表单可以for循环取字段
dict,api封装返回数据时:BaseResponse
mro, 继承顺序
slots,Local对象
fullfilename = '/root/allfile/123.txt'
fullfilenamelist = fullfilename.split('/')
filename = fullfilenamelist[-1]
filepath = fullfilename.replace('/%s' % filename, '')
# 普通下载
# response = make_response(send_from_directory(filepath, filename, as_attachment=True))
# response.headers["Content-Disposition"] = "attachment; filename={}".format(filepath.encode().decode('latin-1'))
# return send_from_directory(filepath, filename, as_attachment=True)
# 流式读取
def send_file():
store_path = fullfilename
with open(store_path, 'rb') as targetfile:
while 1:
data = targetfile.read(20 * 1024 * 1024) # 每次读取20M
if not data:
break
yield data
response = Response(send_file(), content_type='application/octet-stream')
response.headers["Content-disposition"] = 'attachment; filename=%s' % filename # 如果不加上这行代码,导致下图的问题
return response
判断是函数还是方法,主要看是什么类型的实例
from types import FunctionType,MethodType
数据库连接池
pip3 install DBUtils
第三方组件
pip3 install flask-session
# ----------------------------------------
storage = {}
try:
storage["info"]["k1"] = "v1"
except KeyError as e:
storage["info"] = {"k1": "v1"}
上下文管理
- threading.local
为每个线程开辟空间,使得线程之间进行数据隔离
应用:flask的local类,单比threading.local 更牛逼,用的是协程
DBUtils 模式一:为每一个线程创建一个连接 用的是threading。loacl
