1、Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为
2、内置信号
request_started = _signals.signal('request-started') # 请求到来前执行request_finished = _signals.signal('request-finished') # 请求结束后执行 before_render_template = _signals.signal('before-render-template') # 模板渲染前执行template_rendered = _signals.signal('template-rendered') # 模板渲染后执行 got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行 request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否)appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否) appcontext_pushed = _signals.signal('appcontext-pushed') # 请求上下文push时执行appcontext_popped = _signals.signal('appcontext-popped') # 请求上下文pop时执行message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发
3、自定义信号
#!/usr/bin/env python# -*- coding:utf-8 -*-from flask import Flask, current_app, flash, render_templatefrom flask.signals import _signals app = Flask(import_name=__name__) # 自定义信号xxxxx = _signals.signal('xxxxx') def func(sender, *args, **kwargs): print(sender) # 自定义信号中注册函数xxxxx.connect(func) @app.route("/x")def index(): # 触发信号,就会执行信号注册的函数 xxxxx.send('123123', k1='v1') return 'Index' if __name__ == '__main__': app.run()
4、Flask内部的信号流程
a. before_first_request b. 触发 request_started 信号 c. before_request d. 模板渲染 渲染前的信号 before_render_template.send(app, template=template, context=context) rv = template.render(context) # 模板渲染 渲染后的信号 template_rendered.send(app, template=template, context=context) e. after_request f. session.save_session() g. 触发 request_finished信号 如果上述过程出错: 触发错误处理信号 got_request_exception.send(self, exception=e) h. 触发信号 request_tearing_down
补充:触发内部信号
请求结束后执行AppRequest的pop方法时,在最后也会触发信号的执行
class AppContext(object): def pop(self, exc=_sentinel): """Pops the app context.""" try: self._refcnt -= 1 if self._refcnt <= 0: if exc is _sentinel: exc = sys.exc_info()[1] self.app.do_teardown_appcontext(exc) finally: rv = _app_ctx_stack.pop() assert rv is self, 'Popped wrong app context. (%r instead of %r)' \ % (rv, self) appcontext_popped.send(self.app)