八、常用的装饰器
1、常用的装饰器有:before_request、after_request(这两个装饰器有点类似于django的中间件组件)
源码:
1 def preprocess_request(self): 2 """Called before the request is dispatched. Calls 3 :attr:`url_value_preprocessors` registered with the app and the 4 current blueprint (if any). Then calls :attr:`before_request_funcs` 5 registered with the app and the blueprint. 6 7 If any :meth:`before_request` handler returns a non-None value, the 8 value is handled as if it was the return value from the view, and 9 further request handling is stopped. 10 """ 11 12 bp = _request_ctx_stack.top.request.blueprint 13 14 funcs = self.url_value_preprocessors.get(None, ()) 15 if bp is not None and bp in self.url_value_preprocessors: 16 funcs = chain(funcs, self.url_value_preprocessors[bp]) 17 for func in funcs: 18 func(request.endpoint, request.view_args) 19 20 funcs = self.before_request_funcs.get(None, ()) 21 if bp is not None and bp in self.before_request_funcs: 22 funcs = chain(funcs, self.before_request_funcs[bp]) 23 for func in funcs: 24 rv = func() 25 if rv is not None: 26 return rv
1 def process_response(self, response): 2 """Can be overridden in order to modify the response object 3 before it's sent to the WSGI server. By default this will 4 call all the :meth:`after_request` decorated functions. 5 6 .. versionchanged:: 0.5 7 As of Flask 0.5 the functions registered for after request 8 execution are called in reverse order of registration. 9 10 :param response: a :attr:`response_class` object. 11 :return: a new response object or the same, has to be an 12 instance of :attr:`response_class`. 13 """ 14 ctx = _request_ctx_stack.top 15 bp = ctx.request.blueprint 16 funcs = ctx._after_request_functions 17 if bp is not None and bp in self.after_request_funcs: 18 funcs = chain(funcs, reversed(self.after_request_funcs[bp])) 19 if None in self.after_request_funcs: 20 funcs = chain(funcs, reversed(self.after_request_funcs[None])) 21 for handler in funcs: 22 response = handler(response) 23 if not self.session_interface.is_null_session(ctx.session): 24 self.session_interface.save_session(self, ctx.session, response) 25 return response
练习:
1 from flask import Flask, Markup, request, redirect 2 3 4 app = Flask(__name__) 5 6 7 # app.before_first_request_funcs -> list 8 # 将被before_request装饰的函数添加到before_first_request_funcs列表中,在视图函数被执行前执行 9 # 如果某个被装饰的函数有返回值的,就会不在执行对应的视图函数,直接开始执行被after_request装饰器的函数(反向) 10 11 12 @app.before_request 13 def check_home(): 14 if "home" in request.path: 15 return redirect("/") 16 17 18 @app.before_request 19 def usual_bye(): 20 print("Bye") 21 22 23 @app.before_request 24 def usual_input(): 25 print("Hello World!") 26 27 28 # app.after_request_funcs -> list 29 # 将被after_request装饰的函数添加到after_request_funcs列表中,在响应产生后被执行,函数必须要有一个接收response的参数,并且也要返回 30 # 一个响应 31 # 注意:after_request_funcs里面的函数执行的顺序是相反的 32 33 @app.after_request 34 def foo(response): 35 print("foo") 36 return response 37 38 39 @app.after_request 40 def bar(response): 41 print("bar") 42 return response 43 44 45 @app.route("/") 46 def index(): 47 return Markup("index|<a href='/home'>Home</a>") 48 49 50 @app.route("/home") 51 def home(): 52 return "home" 53 54 55 if __name__ == '__main__': 56 app.run("localhost", 80, debug=True)
图示:
2、其他装饰器:errorhandler、template_global、template_filter等
1 # 当发生相应的错误码时,执行对应的函数,返回一个界面良好的404界面 2 @app.errorhandler(404) 3 def show_404(): 4 from flask import render_template 5 return render_template("404.html") 6 7 8 # 可以让所有的模板都使用的函数 9 @app.template_global 10 def gun(a, b): 11 return a + b 12 13 14 # 可以让所有的模板中都使用的过滤器 15 @app.template_filter 16 def f(a, b): 17 return a + b