请求扩展、中间件、请求上下文源码
一、请求扩展
1 before_first_request
当项目启动后,接收到的第一个请求,就会执行before_first_request装饰的函数,执行顺序:谁先注册就谁先执行
2 before_request
请求没有经过响应函数的时候,会执行before_request装饰的函数,谁先注册谁先执行。
只要有一个函数有返回值,后面的所有before_request都不会执行,且响应函数也不会执行。其有没有返回值都不会影响after_request的执行
3 after_request
是再before_request与响应函数执行后执行。他必须接收响应参数(response或res),并且要把响应(response或res)返回。执行顺序是:谁先注册后执行。
#flask里面的请求扩展相当于django中的中间件 from flask import Flask,request app = Flask(__name__) # 1 执行响应函数之前,相当于django中的process_request,再执行响应函数执行一些事情 # 2 请求执行之前,before_request装饰的函数是,谁先注册谁先执行 # 3 如果befor_request中有返回值,那后面的befor_request不会执行,而且响应函数也不会执行.但是after_rquest都会执行 @app.before_request def before1(*args,**kwargs): print('参数',*args,**kwargs) print("我是befor1") return "ok" @app.before_request def before2(): print("我是befor2") # 1、响应函数之后执行的,process_response,就是在执行响应函数之后执行的 # 2、after_request必须接收一个参数,参数为response对象,而且必须返回 # 3、after_request的执行顺序,是谁先注册,后执行 @app.after_request def after1(response): print("响应后的参数",response) print("我是after1") return response @app.after_request def after2(response): print("我是after2") return response # 项目启动后接收到的第一个请求后所要执行的函数,这是整个项目的第一次, # 真的一次,不是和哪个浏览器的第一次有关,就是,你请求过了,再换了浏览器它也不执行 @app.before_first_request def first(): print("我是第一次") @app.route("/") def index(): print("我是响应函数") return "ok" if __name__ == '__main__': app.run()
结果

二、请求上下文 源码:

进 __call__
def __call__(self, environ, start_response): return self.wsgi_app(environ, start_response)
进 上面的 wsgi_ap
def wsgi_app(self, environ, start_response): # ctx就是RequestContext的一个对象,里面包含了请求相关的东西 1、 ctx = self.request_context(environ) error = None try: try: # 就把ctx放到Local对象里面了 2、 ctx.push() # 请求扩展以及响应函数 3、response = self.full_dispatch_request() except Exception as e: error = e response = self.handle_exception(e) except: # noqa: B001 error = sys.exc_info()[1] raise return response(environ, start_response) finally: if self.should_ignore_error(error): error = None ctx.auto_pop(error) def __call__(self, environ, start_response): return self.wsgi_app(environ, start_response) def __repr__(self): return "<%s %r>" % (self.__class__.__name__, self.name)
2、 进 .push()

进 上面标红的
图888

第一次执行app.__call__后, 这些全部都在内存里了 因为这些是 全局的
进 上面标红的

3、进上面的 .full_dispatch_request()

进 上面 标红

进 @app.before_first_request

标绿的意思时

进上面标绿的

继续

进图888中 标黄的LocalProxy


进 看 LocalProxy中 的__getattr__ 方法

进 绿色

上图代码的解释


进 图888 中的蓝色

进 上图绿色

解析

三、请求扩展
4、 teardown_request,一旦遇到错误就会执行,并且把错误传递给teardown_request装饰的函数。
没有错误也会执行,但是是错误为None,他并不能处理错误,只能记录
01、有错

02、没错

5、 errorhandle 可以捕获错误,并且对错误做出响应,返回给用户。
如果你要用errorhandler你必须指定他捕获哪种类型的错误,就必须传错误码,然后就返回值,返回给用户
01、有错

02、没错

6、template_global()
相当于django中的标签,只要定义它,就可以再不把函数对象传递模板的情况下,再模板中直接使用。用法:{{函数名()}}
01、向html传函数:方式一


02、向html传函数:方式二


7、template_filter()
相当于django中的过滤器,它使用和django中的过滤一样的用,但是它可以接收多个参数,无论是几个。用法:{{要过滤的值|函数名(参数)}}


四、中间件
from flask import Flask app = Flask(__name__) class MyMiddleware: def __init__(self,old_wsgi_app): self.old_wsgi_app =old_wsgi_app def __call__(self, environ, start_response): #这befor的befor print("开始之前") ret = self.old_wsgi_app(environ, start_response) #这是after的after print("结束之后") return ret @app.route("/") def index(): return "ok" if __name__ == '__main__': app.wsgi_app = MyMiddleware(app.wsgi_app) app.run()

浙公网安备 33010602011771号