mirror of
https://github.com/django/django.git
synced 2024-12-01 15:42:04 +01:00
Fixed #18454 -- Added ability to pass a list of signals to receiver
.
Added ability to use receiver decorator in the following way: @receiver([post_save, post_delete], sender=MyModel) def signals_receiver(sender, **kwargs): ...
This commit is contained in:
parent
946d3d9f84
commit
d4da08375b
@ -257,14 +257,21 @@ class Signal(object):
|
|||||||
def receiver(signal, **kwargs):
|
def receiver(signal, **kwargs):
|
||||||
"""
|
"""
|
||||||
A decorator for connecting receivers to signals. Used by passing in the
|
A decorator for connecting receivers to signals. Used by passing in the
|
||||||
signal and keyword arguments to connect::
|
signal (or list of signals) and keyword arguments to connect::
|
||||||
|
|
||||||
@receiver(post_save, sender=MyModel)
|
@receiver(post_save, sender=MyModel)
|
||||||
def signal_receiver(sender, **kwargs):
|
def signal_receiver(sender, **kwargs):
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@receiver([post_save, post_delete], sender=MyModel)
|
||||||
|
def signals_receiver(sender, **kwargs):
|
||||||
|
...
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def _decorator(func):
|
def _decorator(func):
|
||||||
signal.connect(func, **kwargs)
|
if isinstance(signal, (list, tuple)):
|
||||||
|
[s.connect(func, **kwargs) for s in signal]
|
||||||
|
else:
|
||||||
|
signal.connect(func, **kwargs)
|
||||||
return func
|
return func
|
||||||
return _decorator
|
return _decorator
|
||||||
|
@ -103,6 +103,9 @@ Django 1.5 also includes several smaller improvements worth noting:
|
|||||||
* In the localflavor for Canada, "pq" was added to the acceptable codes for
|
* In the localflavor for Canada, "pq" was added to the acceptable codes for
|
||||||
Quebec. It's an old abbreviation.
|
Quebec. It's an old abbreviation.
|
||||||
|
|
||||||
|
* The :ref:`receiver <connecting-receiver-functions>` decorator is now able to
|
||||||
|
connect to more than one signal by supplying a list of signals.
|
||||||
|
|
||||||
Backwards incompatible changes in 1.5
|
Backwards incompatible changes in 1.5
|
||||||
=====================================
|
=====================================
|
||||||
|
|
||||||
|
@ -52,10 +52,10 @@ called when the signal is sent by using the
|
|||||||
:meth:`.Signal.connect` method:
|
:meth:`.Signal.connect` method:
|
||||||
|
|
||||||
.. method:: Signal.connect(receiver, [sender=None, weak=True, dispatch_uid=None])
|
.. method:: Signal.connect(receiver, [sender=None, weak=True, dispatch_uid=None])
|
||||||
|
|
||||||
:param receiver: The callback function which will be connected to this
|
:param receiver: The callback function which will be connected to this
|
||||||
signal. See :ref:`receiver-functions` for more information.
|
signal. See :ref:`receiver-functions` for more information.
|
||||||
|
|
||||||
:param sender: Specifies a particular sender to receive signals from. See
|
:param sender: Specifies a particular sender to receive signals from. See
|
||||||
:ref:`connecting-to-specific-signals` for more information.
|
:ref:`connecting-to-specific-signals` for more information.
|
||||||
|
|
||||||
@ -129,10 +129,17 @@ receiver:
|
|||||||
|
|
||||||
Now, our ``my_callback`` function will be called each time a request finishes.
|
Now, our ``my_callback`` function will be called each time a request finishes.
|
||||||
|
|
||||||
|
Note that ``receiver`` can also take a list of signals to connect a function
|
||||||
|
to.
|
||||||
|
|
||||||
.. versionadded:: 1.3
|
.. versionadded:: 1.3
|
||||||
|
|
||||||
The ``receiver`` decorator was added in Django 1.3.
|
The ``receiver`` decorator was added in Django 1.3.
|
||||||
|
|
||||||
|
.. versionchanged:: 1.5
|
||||||
|
|
||||||
|
The ability to pass a list of signals was added.
|
||||||
|
|
||||||
.. admonition:: Where should this code live?
|
.. admonition:: Where should this code live?
|
||||||
|
|
||||||
You can put signal handling and registration code anywhere you like.
|
You can put signal handling and registration code anywhere you like.
|
||||||
@ -182,7 +189,7 @@ Preventing duplicate signals
|
|||||||
In some circumstances, the module in which you are connecting signals may be
|
In some circumstances, the module in which you are connecting signals may be
|
||||||
imported multiple times. This can cause your receiver function to be
|
imported multiple times. This can cause your receiver function to be
|
||||||
registered more than once, and thus called multiples times for a single signal
|
registered more than once, and thus called multiples times for a single signal
|
||||||
event.
|
event.
|
||||||
|
|
||||||
If this behavior is problematic (such as when using signals to
|
If this behavior is problematic (such as when using signals to
|
||||||
send an email whenever a model is saved), pass a unique identifier as
|
send an email whenever a model is saved), pass a unique identifier as
|
||||||
|
@ -4,5 +4,5 @@ Unit-tests for the dispatch project
|
|||||||
|
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from .test_dispatcher import DispatcherTests
|
from .test_dispatcher import DispatcherTests, ReceiverTestCase
|
||||||
from .test_saferef import SaferefTests
|
from .test_saferef import SaferefTests
|
||||||
|
@ -2,7 +2,7 @@ import gc
|
|||||||
import sys
|
import sys
|
||||||
import time
|
import time
|
||||||
|
|
||||||
from django.dispatch import Signal
|
from django.dispatch import Signal, receiver
|
||||||
from django.utils import unittest
|
from django.utils import unittest
|
||||||
|
|
||||||
|
|
||||||
@ -33,6 +33,8 @@ class Callable(object):
|
|||||||
return val
|
return val
|
||||||
|
|
||||||
a_signal = Signal(providing_args=["val"])
|
a_signal = Signal(providing_args=["val"])
|
||||||
|
b_signal = Signal(providing_args=["val"])
|
||||||
|
c_signal = Signal(providing_args=["val"])
|
||||||
|
|
||||||
class DispatcherTests(unittest.TestCase):
|
class DispatcherTests(unittest.TestCase):
|
||||||
"""Test suite for dispatcher (barely started)"""
|
"""Test suite for dispatcher (barely started)"""
|
||||||
@ -123,3 +125,29 @@ class DispatcherTests(unittest.TestCase):
|
|||||||
garbage_collect()
|
garbage_collect()
|
||||||
a_signal.disconnect(receiver_3)
|
a_signal.disconnect(receiver_3)
|
||||||
self._testIsClean(a_signal)
|
self._testIsClean(a_signal)
|
||||||
|
|
||||||
|
|
||||||
|
class ReceiverTestCase(unittest.TestCase):
|
||||||
|
"""
|
||||||
|
Test suite for receiver.
|
||||||
|
|
||||||
|
"""
|
||||||
|
def testReceiverSingleSignal(self):
|
||||||
|
@receiver(a_signal)
|
||||||
|
def f(val, **kwargs):
|
||||||
|
self.state = val
|
||||||
|
self.state = False
|
||||||
|
a_signal.send(sender=self, val=True)
|
||||||
|
self.assertTrue(self.state)
|
||||||
|
|
||||||
|
def testReceiverSignalList(self):
|
||||||
|
@receiver([a_signal, b_signal, c_signal])
|
||||||
|
def f(val, **kwargs):
|
||||||
|
self.state.append(val)
|
||||||
|
self.state = []
|
||||||
|
a_signal.send(sender=self, val='a')
|
||||||
|
c_signal.send(sender=self, val='c')
|
||||||
|
b_signal.send(sender=self, val='b')
|
||||||
|
self.assertIn('a', self.state)
|
||||||
|
self.assertIn('b', self.state)
|
||||||
|
self.assertIn('c', self.state)
|
||||||
|
Loading…
Reference in New Issue
Block a user