2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								.. _signals:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Signals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								=======
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								.. versionadded:: 0.6
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Starting with Flask 0.6, there is integrated support for signalling in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Flask.  This support is provided by the excellent `blinker`_ library and
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								will gracefully fall back if it is not available.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								What are signals?  Signals help you decouple applications by sending
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								notifications when actions occur elsewhere in the core framework or
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								another Flask extensions.  In short, signals allow certain senders to
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								notify subscribers that something happened.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Flask comes with a couple of signals and other extensions might provide
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								more.  Also keep in mind that signals are intended to notify subscribers
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								and should not encourage subscribers to modify data.  You will notice that
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								there are signals that appear to do the same thing like some of the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								builtin decorators do (eg: :data:`~flask.request_started` is very similar
							 | 
						
					
						
							
								
									
										
										
										
											2016-04-02 05:12:25 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								to :meth:`~flask.Flask.before_request`).  However, there are differences in
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								how they work.  The core :meth:`~flask.Flask.before_request` handler, for
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								example, is executed in a specific order and is able to abort the request
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								early by returning a response.  In contrast all signal handlers are
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								executed in undefined order and do not modify any data.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								The big advantage of signals over handlers is that you can safely
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-09 17:03:08 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								subscribe to them for just a split second.  These temporary
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-23 08:36:55 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								subscriptions are helpful for unit testing for example.  Say you want to
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								know what templates were rendered as part of a request: signals allow you
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								to do exactly that.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Subscribing to Signals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								----------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								To subscribe to a signal, you can use the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								:meth:`~blinker.base.Signal.connect` method of a signal.  The first
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								argument is the function that should be called when the signal is emitted,
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								the optional second argument specifies a sender.  To unsubscribe from a
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								signal, you can use the :meth:`~blinker.base.Signal.disconnect` method.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								For all core Flask signals, the sender is the application that issued the
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								signal.  When you subscribe to a signal, be sure to also provide a sender
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-09 17:03:08 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								unless you really want to listen for signals from all applications.  This is
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								especially true if you are developing an extension.
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2017-05-23 08:36:55 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								For example, here is a helper context manager that can be used in a unit test
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-09 17:03:08 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								to determine which templates were rendered and what variables were passed
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								to the template::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    from flask import template_rendered
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    from contextlib import contextmanager
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @contextmanager
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def captured_templates(app):
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        recorded = []
							 | 
						
					
						
							
								
									
										
										
										
											2011-10-08 03:19:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        def record(sender, template, context, **extra):
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            recorded.append((template, context))
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        template_rendered.connect(record, app)
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        try:
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 23:22:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            yield recorded
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        finally:
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            template_rendered.disconnect(record, app)
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								This can now easily be paired with a test client::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    with captured_templates(app) as templates:
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        rv = app.test_client().get('/')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert rv.status_code == 200
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert len(templates) == 1
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        template, context = templates[0]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert template.name == 'index.html'
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        assert len(context['items']) == 10
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-10-08 03:19:03 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Make sure to subscribe with an extra ``**extra`` argument so that your
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								calls don't fail if Flask introduces new arguments to the signals.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								All the template rendering in the code issued by the application `app`
							 | 
						
					
						
							
								
									
										
										
										
											2014-11-05 12:39:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								in the body of the ``with`` block will now be recorded in the `templates`
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								variable.  Whenever a template is rendered, the template object as well as
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								context are appended to it.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Additionally there is a convenient helper method
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-09 17:03:08 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								(:meth:`~blinker.base.Signal.connected_to`)  that allows you to
							 | 
						
					
						
							
								
									
										
										
										
											2011-11-21 00:03:37 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								temporarily subscribe a function to a signal with a context manager on
							 | 
						
					
						
							
								
									
										
										
										
											2010-11-19 20:25:45 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								its own.  Because the return value of the context manager cannot be
							 | 
						
					
						
							
								
									
										
										
										
											2015-02-09 17:03:08 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								specified that way, you have to pass the list in as an argument::
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    from flask import template_rendered
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-10-08 03:09:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def captured_templates(app, recorded, **extra):
							 | 
						
					
						
							
								
									
										
										
										
											2010-08-15 10:52:11 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        def record(sender, template, context):
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 17:12:58 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								            recorded.append((template, context))
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 22:05:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        return template_rendered.connected_to(record, app)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-11-19 20:25:45 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								The example above would then look like this::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    templates = []
							 | 
						
					
						
							
								
									
										
										
										
											2011-10-08 03:09:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    with captured_templates(app, templates, **extra):
							 | 
						
					
						
							
								
									
										
										
										
											2010-11-19 20:25:45 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        ...
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        template, context = templates[0]
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 22:05:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								.. admonition:: Blinker API Changes
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   The :meth:`~blinker.base.Signal.connected_to` method arrived in Blinker
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   with version 1.1.
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Creating Signals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								----------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								If you want to use signals in your own application, you can use the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								blinker library directly.  The most common use case are named signals in a
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								custom :class:`~blinker.base.Namespace`..  This is what is recommended
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								most of the time::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    from blinker import Namespace
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    my_signals = Namespace()
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Now you can create new signals like this::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    model_saved = my_signals.signal('model-saved')
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								The name for the signal here makes it unique and also simplifies
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								debugging.  You can access the name of the signal with the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								:attr:`~blinker.base.NamedSignal.name` attribute.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								.. admonition:: For Extension Developers
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2011-08-13 06:22:10 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								   If you are writing a Flask extension and you want to gracefully degrade for
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   missing blinker installations, you can do so by using the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   :class:`flask.signals.Namespace` class.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-04 23:39:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								.. _signals-sending:
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Sending Signals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								---------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								If you want to emit a signal, you can do so by calling the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								:meth:`~blinker.base.Signal.send` method.  It accepts a sender as first
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								argument and optionally some keyword arguments that are forwarded to the
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								signal subscribers::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    class Model(object):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        ...
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								        def save(self):
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								            model_saved.send(self)
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Try to always pick a good sender.  If you have a class that is emitting a
							 | 
						
					
						
							
								
									
										
										
										
											2014-11-05 12:39:54 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								signal, pass ``self`` as sender.  If you are emitting a signal from a random
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								function, you can pass ``current_app._get_current_object()`` as sender.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								.. admonition:: Passing Proxies as Senders
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   Never pass :data:`~flask.current_app` as sender to a signal.  Use
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   ``current_app._get_current_object()`` instead.  The reason for this is
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   that :data:`~flask.current_app` is a proxy and not the real application
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								   object.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-04 23:39:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Signals and Flask's Request Context
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								-----------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-04 23:41:40 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Signals fully support :ref:`request-context` when receiving signals.
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Context-local variables are consistently available between
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								:data:`~flask.request_started` and :data:`~flask.request_finished`, so you can
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								rely on :class:`flask.g` and others as needed.  Note the limitations described
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								in :ref:`signals-sending` and the :data:`~flask.request_tearing_down` signal.
							 | 
						
					
						
							
								
									
										
										
										
											2012-04-04 23:39:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 22:05:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Decorator Based Signal Subscriptions
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								------------------------------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								With Blinker 1.1 you can also easily subscribe to signals by using the new
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								:meth:`~blinker.base.NamedSignal.connect_via` decorator::
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    from flask import template_rendered
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								    @template_rendered.connect_via(app)
							 | 
						
					
						
							
								
									
										
										
										
											2011-10-08 03:09:12 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								    def when_template_rendered(sender, template, context, **extra):
							 | 
						
					
						
							
								
									
										
										
										
											2019-10-26 14:19:00 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								        print f'Template {template.name} is rendered with {context}'
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-20 22:05:01 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								Core Signals
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								------------
							 | 
						
					
						
							| 
								
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2015-06-11 00:37:07 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								Take a look at :ref:`core-signals-list` for a list of all builtin signals.
							 | 
						
					
						
							
								
									
										
										
										
											2010-07-17 21:25:53 +08:00
										 
									 
								 
							 | 
							
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2013-03-22 05:04:06 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								
							 | 
						
					
						
							
								
									
										
										
										
											2018-04-13 13:54:11 +08:00
										 
									 
								 
							 | 
							
								
									
										
									
								
							 | 
							
								
							 | 
							
							
								.. _blinker: https://pypi.org/project/blinker/
							 |