flask信号
2018-06-18 02:05:58来源:未知 阅读 ()
flask信号
Flask框架中的信号基于blinker,其主要就是让开发者可是在flask请求过程中定制一些用户行为。
安装:pip install blinker
1、信号是什么?
- 在代码中信号可以理解为在当程序走到一定的位置之后,做指定的操作,flask为我们提供了10个信号
1 request_started = _signals.signal('request-started') # 请求到来前执行 2 request_finished = _signals.signal('request-finished') # 请求结束后执行 3 4 before_render_template = _signals.signal('before-render-template') # 模板渲染前执行 5 template_rendered = _signals.signal('template-rendered') # 模板渲染后执行 6 7 got_request_exception = _signals.signal('got-request-exception') # 请求执行出现异常时执行 8 9 request_tearing_down = _signals.signal('request-tearing-down') # 请求执行完毕后自动执行(无论成功与否) 10 appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 请求上下文执行完毕后自动执行(无论成功与否) 11 12 appcontext_pushed = _signals.signal('appcontext-pushed') # 请求上下文push时执行 13 appcontext_popped = _signals.signal('appcontext-popped') # 请求上下文pop时执行 14 message_flashed = _signals.signal('message-flashed') # 调用flask在其中添加数据时,自动触发
2、源码剖析
执行顺序:
1 before_first_request 2 触发 request_started 信号 3 before_request 4 模板渲染前的信号 before_render_template.send(app, template=template, context=context) 5 模板渲染 6 渲染后的信号 template_rendered.send(app, template=template, context=context) 7 after_request 8 session.save_session() 9 触发 request_finished信号 10 如果full_dispatch_request中出错: 11 触发错误处理信号 got_request_exception.send(self, exception=e) 12 触发信号 request_tearing_down
2-1、 request_started 请求到来前执行,在这里我们发现的请求扩展中的before_first_request和before_request的源码处理,由此可见request_started的执行顺序为before_first_request之后before_request之前。
位置: app.__call__ --> app.wsgi_app() --> full_dispatch_request()
1 def full_dispatch_request(self): 2 3 # before_first_request,这里处理的是否是第一次请求 4 self.try_trigger_before_first_request_functions() 5 try: 6 # 触发request_started信号 7 request_started.send(self) 8 9 # before_request,处理机制 10 rv = self.preprocess_request() 11 if rv is None: 12 # 执行视图函数 13 rv = self.dispatch_request() 14 except Exception as e: 15 rv = self.handle_user_exception(e) 16 return self.finalize_request(rv) # 请求结束后执行
2-2、 request_finished 请求结束后执行,在after_request和保存session之后执行
1 def finalize_request(self, rv, from_error_handler=False): 2 3 response = self.make_response(rv) 4 try: 5 response = self.process_response(response) 6 # 请求结束后触发 7 request_finished.send(self, response=response) 8 except Exception: 9 if not from_error_handler: 10 raise 11 self.logger.exception('Request finalizing failed with an ' 12 'error while handling an error') 13 return response
2-3、 got_request_exception 在 full_dispatch_request() 执行出现异常时执行
1 def handle_exception(self, e): 2 exc_type, exc_value, tb = sys.exc_info() 3 # 出错时触发信号 4 got_request_exception.send(self, exception=e) 5 handler = self._find_error_handler(InternalServerError())
2-4、 before_render_template 模板渲染之前执行
入口: render_template() --> _render()
1 def _render(template, context, app): 2 # 模板渲染之前触发 3 before_render_template.send(app, template=template, context=context) 4 rv = template.render(context) # 真正的模板渲染 5 # 模板渲染之后触发 6 template_rendered.send(app, template=template, context=context) 7 return rv
2-5、 template_rendered 模板渲染之后执行(同上)
2-6、 appcontext_pushed 请求上下文push时执行
入口: wsgi_app() --> ctx.push() --> app_ctx.push()
1 def push(self): 2 3 self._refcnt += 1 4 if hasattr(sys, 'exc_clear'): 5 sys.exc_clear() 6 # _app_ctx_stack是LocalProxy对象,又创建了一个Local对象 7 _app_ctx_stack.push(self) 8 # 请求上下文push时执行 9 appcontext_pushed.send(self.app) 10 11 def pop(self, exc=_sentinel): 12 13 try: 14 self._refcnt -= 1 15 if self._refcnt <= 0: 16 if exc is _sentinel: 17 exc = sys.exc_info()[1] 18 self.app.do_teardown_appcontext(exc) # 两个自动执行信号入口 19 finally: 20 rv = _app_ctx_stack.pop() 21 assert rv is self, 'Popped wrong app context. (%r instead of %r)' \ 22 % (rv, self) 23 # 请求上下文pop时执行 24 appcontext_popped.send(self.app) 25
2-7、 appcontext_popped 请求上下文pop时执行(同上)
2-8、 request_tearing_down 请求结束后自动执行,无论成功与否
入口:在上面找 self.app.do_teardown_appcontext(exc)
1 def do_teardown_request(self, exc=_sentinel): 2 3 if exc is _sentinel: 4 exc = sys.exc_info()[1] 5 funcs = reversed(self.teardown_request_funcs.get(None, ())) 6 bp = _request_ctx_stack.top.request.blueprint 7 if bp is not None and bp in self.teardown_request_funcs: 8 funcs = chain(funcs, reversed(self.teardown_request_funcs[bp])) 9 for func in funcs: 10 func(exc) 11 # 请求完毕自动执行 12 request_tearing_down.send(self, exc=exc) 13 14 def do_teardown_appcontext(self, exc=_sentinel): 15 16 if exc is _sentinel: 17 exc = sys.exc_info()[1] 18 for func in reversed(self.teardown_appcontext_funcs): 19 func(exc) 20 # 请求上下文完毕自动执行 21 appcontext_tearing_down.send(self, exc=exc)
2-9、 appcontext_tearing_down 请求上下文完毕后自动执行,无论成功与否(同上)
2-10、 message_flashed 在flashed中添加数据时自动执行(入口:flash)
1 def flash(message, category='message'): 2 3 flashes = session.get('_flashes', []) 4 flashes.append((category, message)) 5 session['_flashes'] = flashes 6 # 调用flask在其中添加数据时,自动触发 7 message_flashed.send(current_app._get_current_object(), 8 message=message, category=category)
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
上一篇:编程语言的分类
- Flask request接口获取参数 2019-08-13
- Django中信号signals简单使用 2019-07-24
- Flask的上下文管理 2019-07-24
- Flask学习之旅--数据库 2019-07-24
- 基于flask的网页聊天室(二) 2019-05-13
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash