1.django 和 flask的区别?
他们两个相同点都是基于wsig
最大的不同点 是 对于django而言,请求相关的数据 是通过封装到request里面,通过把request传递过去,取响应的数据的。
而 对于 flask 来说,请求相关的数据 是通过上下文管理完成的;
2.什么是wsgi?
web服务网关接口, 就是一个协议(规范),实现该协议的模块:
- wsgiref
- werkzeug
实现其协议的模块本质上就是socket服务端 , 用于接收用户请求,并处理。
一般web框架基于wsgi实现,这样 实现关注点分离(web框架更关注于 接收到请求之后再做逻辑的处理 ;而wsgi则关注于获取socket的请求)
Flask源码的入口:
from werkzeug.serving import run_simple from werkzeug.wrappers import Response # run_simple(host, port, self, **options) 自动的给第3个参数加(),用来调用。 # app.__call__ class Flask(): def __call__(self, environ, start_response): response = Response("hello") return response(environ, start_response) def run(self,host="127.0.0.1",port=8000): run_simple(host, port, self) app = Flask() if __name__ == "__main__": app.run()
这里重点分析app.run() 都干了什么?
首先,执行app.run() 时,源码中显示执行了执行run_simple() 方法,源码中run_simple() 方法的参数是run_simple(host, port, self, **options) ,这里重点看第三个参数self,因为app是flask的实例化对象,因此self就是指flask的实例化对象app,而上例中我们知道当有请求进来的时候,执行了app(),我们知道函数加括号是执行,而对象加括号会自动执行__call__方法,也就是说app.run() 其实是监听了flask类中的__call__方法,
def add:
return ".."
run_simple(host, port, add, **options) , 请求一旦执行将会自动的执行这个add函数,证明 给第三个参数加了括号;如果第三个参数 是对象的话,就会执行 类中的__call__方法。
3. Flask 提供功能:
-配置文件
-所有的配置文件都是在app.config中
- 直接可以配置 app.config["xx"] = 123
- 还可以写一个配置类, 通过app.config.from_object("类的路径") ;配置类也可继承,可得到不同环境下的配置。
- 通过 importlib 以及 getattr 通过 "类的路径"字符串 得到 类,然后dir(cls),isupper,得到这个类中大写的配置属性
应用 : importlib 和 getattr
- django中间件
- rest framework 的全局配置。
-session
- 加密后放置在用户浏览器的cookie中
- 流程:
- 请求到来
- 视图函数
- 请求结束
- 配置文件
默认的session有效时间为31day;
-闪现
- 基于session.pop 实现的,实现了 只能取一次的效果
-路由
- 装饰器(带参数的装饰器)
- 自定义的装饰器放在下面
- 3个参数 :@app.route('/delete/<int:s_id>', methods=["GET", "POST"],endpoint="") ;
endpoint 反向生成url; url_for
-视图
-FBV
-特殊的装饰器
-中间件
- __call__
-模板
-请求和响应
-请求request
-响应:
-4种响应
1.路由 + 视图
''' 带参数的装饰器的原理 def route(self, rule, **options): def decorator(f): endpoint = options.pop("endpoint", None) self.add_url_rule(rule, endpoint, f, **options) return f return decorator ''' ''' @app.route('/index', methods=["GET", "POST"]) 执行的过程: 1.先执行 decorator = app.route('/index', methods=["GET", "POST"]) 2. @decorator def index(): pass decorator(index) '''
2. session 实现原理(源码):
session的流程图
3. 蓝图:
目标: 给开发者提供目录结构
其他:
- 自定义的模板,静态文件
- 给某一类的Url添加前缀
app.register_blueprint(ac,url_prefix='/api')
- 给某一类的url添加before_request
@ac.before_request
def xxx():
print("ac.before_request")
@ac.route('/login')
def login():
return render_template("login.html")
4. threading.local
给每个线程开辟自己的一个空间,进行数据隔离。
#把他封装为一个类,这样 跟 threading.local 一样的使用.
# __getattr__ (是在 obj.xxx 的取值的时候调用的 ); __setattr__(obj.xxx = 123 设置值的时候调用的)
#threading.local 的加强版 (不仅包含线程 也包含协程 )
import greenlet try: get_ident = threading.get_ident except Exception: get_ident = greenlet.getcurrent class Local(object): DICT = {} def __getattr__(self, item): ident_value = get_ident() if ident_value in self.DICT: return self.DICT[ident_value][item] return None def __setattr__(self, key, value): ident_value = threading.get_ident() if ident_value in self.DICT: self.DICT[ident_value][key] = value else: self.DICT[ident_value] = {key:value} obj = Local() def func(i): global v v = i obj.xxx = v time.sleep(0.5) print(obj.xxx) print(threading.get_ident(), i) for i in range(10): t = threading.Thread(target=func,args=(i,)) t.start()
5.上下文管理
https://www.cnblogs.com/zenghui-python/articles/11693202.html
flask中的上下文管理机制分为请求上下文和应用上下文两大方面,通过上下文的管理机制,实现了即去即用的一个特色。
flask的上下文管理是基于local来实现的数据存储。数据隔离。