Pyhton全栈的知识点(5)

1. 对于django来说,内部组件特别多,自身功能强大,有点大而全,而flask,内置组件很少,但是它的第三方组件很多,
    扩展性强,有点短小精悍,而它们之间也有相似之处,
  因为它们两个框架都没有写sockte,都是基于wsgi协议做的,在此之外,flask框架中的上下文管理较为耀眼。
  
  相同点:它们两个框架都没有写sockte,都是基于wsgi协议做的
  请求相关数据传递的方式不同:django:通过传递request参数取值
                flask: request的模块
           组件不同:django组件多
                flask组件少,第三方组件丰富
    注意: 使用上下文管理机制
    -threading.local()/greenlet.get_current()?---》Local的作用?
    作用:为每个线/携程程创建一个独立的空间,使得线程对自己空间中的数据进行操作(数据隔离)。
    应用:DBUtils中为每个线程创建一个数据库链接时使用
    -如何获取一个线程的唯一标记:threading.get_ident()
    -再次根据线程唯一标记,设置一个大内存字典的key,值就是线程空间中的数据
        -DBUtils线程池的模式也是为每个线程创建一个链接
    -SQLAlchemy的create_engine也会创建线程池以供使用

2. session 
    两个Local和LocalStack分别对应ctx和app_ctx
    请求上下文管理(ctx):request,session 
    应用上下文管理(ap_ctx)
        - 请求到来之后wsgi会触发__call__方法,由__call__方法再次调用wsgi_app方法
        - 在wsgi_app方法中:
            - 首先将 请求相关+空session 封装到一个RequestContext对象中,即:ctx。
            - 将ctx交给LocalStack对象,再由LocalStack将ctx添加到Local中,Local大字典结构:
                __storage__ = {
                    1231:{stack:[ctx] }
                }
            - 根据请求中的cookie中提取名称为session_id对应的值,对cookie进行加密+反序列化,再次赋值给ctx中的session
            
            -> LocalStack获取Local中的数据后,视图函数通过LocalProxy,获取LocalStack中相对应的值
            - 增删改查
            - 把session中的数据再次写入到cookie中。
            - 将ctx删除
        - 结果返回给用户浏览器
        - 断开socket连接

3. 问题:
    为什么要把 ctx=request/session    app_ctx = app/g  分开?
      答:编写离线脚本时,需要配置文件,而配置文件存放在app中,并不需要请求相关数据 
        所以把app和请求相关的数据分开。如果只是需要g传递数据,则在g的生命周期中完全够用     
    在web runtime时,栈中永远只有一个ctx,或者app_ctx;
        在使用离线脚本时,则可能存在多个,但是数据并不会混杂,通过with语句和top取值(-1)可以分层次获取   

4. Flask中g的生命周期?
    在请求触发__call__调用wsgi_app时,生成app_ctx=AppContext(app,g)
    在请求结束时app_ctx.pop()结束g

5. g和session一样吗?
    g是在有请求时被创建,请求结束时删除,下次请求又是一个新的g
    session会被加密序列化写入用户cookie,下次请求解密反序列化就有

6. g和全局变量一样吗?
    全局变量在程序启动时只生成一次,有且只有这一个变量
    g在请求时被生成,请求结束时被删除,是临时可创建变量

7.依赖的wsgi(服务器网关接口): werkzurg

8. 配置文件
    可以设置一个跟Django差不多的settings配置文件,通过app.config.from_object("settings.xxx")路径,
    具体实现是通过importlib模块和getattr反射找到“字符串路径”,再引用配置相关信息
    
9. 路由系统 
    -基于装饰器实现的路由系统
    -endpoint,反向生成URL,默认函数名
    -url_for("函数名" or endpoint)--------注意endpoint反向生成url时有同名,
        需要导入import functools -> @functools.wraps(func) 保留原函数的原信息
    -functool.partial   偏函数(减少用户输入函数参数)
    -动态路由:@app.route("/index/<int:nid>")   传递参数使用
10. 视图
     -基于反射区别method请求
    -FBV
        路由设置:@app.route("/xxxx")
    -CBV
        methods = ["GET",]        decorators = ["wrapper"]
        路由设置:app.add_url_rule("/xxx", None, UserView.as_view('aaa'))
11. 请求相关
        # 请求相关信息
        # request.method    request.path
        # request.args      request.full_path
        # request.form      request.url
        # request.values    request.files
        # request.cookies   request.headers
12. 响应 
    响应体:
        return "字符串"      return jsonify({"k1": "v1"})
        return render_template("xx.html")
        return redirect("/xxxx")
    定制响应体:
        -面向对象的封装
        obj = make_response("字符串")
        obj.headers["k1"] = "v1"
        obj.set_cookie("key", "value")
        return obj
    设置全局访问权限:
    @app.before_request
    def xxx():
        if request.path == '/login':
        return None

        if session.get('user'):
        return None

        return redirect('/login')
13. 模板渲染
    -基本数据类型:可以执行python语法
    -传入函数:
        -django, 自动执行
        -flask, 需要手动加括号执行
    -全局定义函数
        @app.template_global()
        def xx(a1, a2):
            # {{sb(1,9)}}
            return a1 + a2
    -添加撒选条件
        @app.template_filter()
        def db(a1, a2, a3):
            # {{ 1|db(2,3) }}
            return a1 + a2 + a3
    -模板继承跟django差不多
    -预定义模块(不传值看不见,传值就启动)
    -安全
        - 前端: {{u|safe}}
        - 后端: MarkUp("asdf")
     
14. 闪现
    -在session中存储一个数据,读取时通过pop将数据移除,获取的值返回给用户

15. 中间件 
    - call方法什么时候触发?
        - 用户发起请求时,才执行。

16. 蓝图(blueprint)
    -目标:给开发者提供目录结构
    其他:
        - 自定义模板、静态文件
        - 某一类url添加前缀
        - 给一类url添加before_request
            
17. 特殊装饰器
     -放在列表,循环执行
    1. before_request      (请求相关)
    2. after_request
    3. before_first_request

    4. template_global      (模板相关)
    5. template_filter

    6. errorhandler   (可以自定义错误信息)

18.before_request的执行时机(源码实现:存放在一个列表)Local执行之后,视图执行之前

19. threading.local (DBUtils组件创建一个线程池)

20. 为什么导入request,就可以使用?
    每次执行request.xx方法时,会触发LocalProxy对象的__getattr__等方法,由方法每次动态的使用
    LocalStack去Local中获取数据。

21.扩展:
    1. flask-session 
    2. DBUtils       其他地方也可以使用
    3. wtforms
    4. sqlalchemy
原文地址:https://www.cnblogs.com/Guishuzhe/p/9824934.html