03. 中间件、蓝图、flask请求上下文

一、中间件(了解)

from flask import Flask

app = Flask(__name__)


@app.route('/')
def index():
    return 'Hello World!'


# 模拟中间件
class Md(object):
    def __init__(self, old_wsgi_app):
        self.old_wsgi_app = old_wsgi_app

    def __call__(self, environ, start_response):
        print('开始之前')

        ret = self.old_wsgi_app(environ, start_response)
        print('结束之后')
        return ret


if __name__ == '__main__':
    # 1 当执行app.run方法的时候,最终执行run_simple,最后执行app(),也就是在执行了app.__call__方法
    # 2 在__call__里面,执行的是self.wsgi_app(),那我们希望在执行他本身的wsgi之前做点事情。
    # 3 所以我们先用Md类中__init__,保存之前的wsgi,然后我们用将app.wsgi转化成Md的对象。
    # 4 那执行新的的app.wsgi_app,就是执行Md的__call__方法。
    # 把原来的wsgi_app替换为自定义的,
    aaa=Md(app.wsgi_app)
    app.wsgi_app = aaa
    app.run()
    # flask请求来了会执行,执行app()--->触发:类的__call__
    # app.__call__---->self.wsgi_app(environ, start_response)
    # 请求来了以后,会执行Md对象的__call__
    # aaa(environ, start_response)--->Md类的__call__()

二、蓝图

1、什么是蓝图,有什么作用?

蓝图是一个类的对象
用来划分项目目录,避免使用app划分目录的时候出现循环导入问题

2、使用步骤:

#(1)实例化得到一个蓝图对象
    from flask import Blueprint
    account = Blueprint('account', __name__)

#(2)像使用app=Flask(__name__)一样使用蓝图,注册路由,但是要多传一个name参数,这里用的account
    @account.route('/login.html', methods=['GET', "POST"])
    def login():
        return render_template('login.html')

#(3)在app中注册蓝图
    from .views.account import account
    app.register_blueprint(account)

3、注意点

#1 蓝图注册进app时,指定前缀(类似于路由分发)
	app.register_blueprint(admin, url_prefix='/admin')
#2 蓝图对象在实例化的时候,可以指定当前蓝图使用哪个模板文件夹和静态文件夹
  #如果不指定,默认用app的,查找顺序是先从自己里面找,找不到再找app的
	web = Blueprint('web',__name__,template_folder='templates',static_folder='static')

#3 蓝图对象有自己的请求扩展,请求扩展只属于当前蓝图
# 只有访问当前蓝图管理的路径才会触发请求扩展
	web = Blueprint('web', __name__,template_folder='templates',static_folder='static')
	@web.before_request
	def web_request():
    	print('web request')
        
    @web.after_request
    def web_after(response):
        print(response)
        return response

三、flask请求上下文

1 当flask启动后,等待客户端请求
2 一旦请求来了:app()--->app.__call__()---->app.wsgi_app()
3 wsgi_app()源码如下:(flask执行流程)
    # environ:http请求字典
    # 返回一个ctx=RequestContext,对象中有request对象、session对象、闪现。。。
    ctx = self.request_context(environ)
    error = None
    try:
        try:
            # 把ctx对象放到了全局变量_request_ctx_stack中
            # _request_ctx_stack全局变量是LocalStack的对象
            # 所以ctx.push()就是执行的LocalStack类的push方法
                '''
                def push(self, obj):
                    rv = getattr(self._local, "stack", None)
                    if rv is None:
                        self._local.stack = rv = []
                        rv.append(obj)
                        return rv
                 '''
            ctx.push()
            # 执行请求扩展的东西(before_first_request,before_request,after_request)
            # 根据路径执行视图函数
            response = self.full_dispatch_request()
        except Exception as e:
            error = e
            response = self.handle_exception(e)
        except: 
            error = sys.exc_info()[1]
            raise
        return response(environ, start_response)
    finally:
        if self.should_ignore_error(error):
            error = None
        ctx.auto_pop(error)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值