flask源码分析

1、flask和django的区别
django自带组件,flask需要第三方支持
django上下文管理是通过request参数传递,flask基于上下文管理实现的应用上下文(app,g)和请求上下文(request,session)
2、flask的生命周期
浏览器 -> wsgi(wekzug) -> before_request -> view -> after_request
3、wsgi的本质
socket服务端
4、flask蓝图的作用
默认flask通过一个脚本实现服务,但由于项目业务科能比较多,为了方便业务的拆分,我们会创建多个文件(蓝图)进行管理
5、flask的蓝图和django的app区别
相同点:都是用于业务拆分、需要注册使用、都可以在自己内部定义模板和静态文件
不同的:注册位置不同(django在settings,flask在app中),flask中间件(应用于每个app)比django中间件(应用于整个请求周期)应用粒度更细、django的app内置了很多,flask蓝图没有内置
6、在app = Flask(__name__)对象中可以传入静态文件、模板配置
7、通过app.config读取配置文件(localsettings.py)
8、特殊装饰器
before_first_request
before_request
after_request
route
template_global
template_filter
9、为flask试图设置装饰器
位置
functools.wrappers
10、flask可以定义FBV和CBV,底层就是反射
11、flask中内置了session,session的数据以加密的形式放入cookie中
具体流程:请求进来,创建俩个对象(request_ctx,app_ctx),request_ctx中session一开始是None,flask内部会去请求携带的cookie中拿到值解密,放到request_ctx的session中,经过中间件,视图函数(视图函数中操作request_ctx中的session),响应走时,拿到session加密放入cookie,再将request_ctx销毁。
12、flask本身没有模板,用的第三方的jinja2模板
13、threading.local 为每个线程开辟内存空间,方便每个线程存取值
14、自定义threading.local,内部维护一个字典,以线程/协程id为key
15、localstack类,在local中维护了一个栈
{"线程id":{"stack":[ctx,]}}
16、flask源码中单例模式
_request_ctx_stack = LocalStack()  放的request,session
_app_ctx_stack = LocalStack() 放的app,g
17、flask的请求流程
.请求准备阶段
.请求到来
-创建两个ctx = RequestContext对象,app_ctx = AppContext对象放入local中
-before_request/view/after_request
-销毁ctx/app_ctx
18、g是什么
一次请求中 的全局变量
19、数据库连接池
用的DBUtils模块
20、flask源码中使用代理模式localproxy
用代理localproxy来实现request.方法,session[key]
flask源码流程
项目启动
.实例化flask对象
app = Flask(__name__)
1、对app对象封装一些初始化的值
  app.static_url_path
  app.static_folder
  app.template_folder
  app.view_functions = {}
2、添加静态文件路由
  self.add_url_rule(
    self.static_url_path + "/",
    endpoint = "static",
    host = static_host,
    view_func = self.send_static_file,
  )
3、实例化url_map对象,以后在map对象中放url和endpoint的对应关系,view_functions里放着endpoint和view的对应关系

.加载配置文件(给app的config进行赋值)
from flask import Flask
app = Flask(__name__,static_url_path='/xx')
app.config.from_object('xx.xx')
1、读取配置文件中的所有键值对,并将键值对全部放到config对象(config是一个字典)
2、把包含所有配置文件的config对象赋值给app.config

.添加路由映射
@app.route('/index')
def index():
    return 'hello world'
1、将url = '/index'和methods = [GET,POST]和endpoint = 'index'封装到Rule对象
2、将Rule对象添加到app.url_map中
3、把endpoint和函数的对应关系放到app.view_functions中

.运行flask
from flask import Flask
app = Flask(__name__)
@app.route('/index')
def index():
    return 'hello world'

if __name__ == "__main__":
    app.run()
1、内部调用了werkzeug的run_simple,内部创建socket,监听ip和端口,等待用户请求到来
2、一旦有用户请求,app()运行,执行app.__call__方法
class Flask(object):
    def __call__(self, environ, start_response):
        pass
    def run(self):
        run_simple(host, port, self, **options)
        
        
        
用户请求到来
.创建ctx = RequestContext对象,其内部封装了Request对象和Session对象
.创建app_ctx = AppContext对象,其内部封装了app和g
.然后ctx.push触发将ctx和app_ctx分别通过自己的localstack对象将其放入到local中,localstack的本质是以线程ID为key,以{"stack":{}}为value的字典
.执行所有的before_request函数
.执行视图函数
.执行所有的after_request函数
.session加密放到cookie中
.销毁ctx和app_ctx

你可能感兴趣的:(flask,flask,python,后端)