diff options
| author | Amar <100243770+aadeina@users.noreply.github.com> | 2026-03-06 06:17:30 +0000 |
|---|---|---|
| committer | Jacob Walls <jacobtylerwalls@gmail.com> | 2026-03-09 08:43:16 -0400 |
| commit | b9172e90eb7eb379be994cd63c9705b7f2be6a1a (patch) | |
| tree | 3ab4eb8c54f355a83b19d01e1321ae85457b0724 | |
| parent | d9687f163d4b379cd5d85f3fade9f0e0e91b4022 (diff) | |
[6.0.x] Fixed #36600 -- Clarified the use cases for dispatch_uid in signal connection.
Co-authored-by: Jacob Walls <jacobtylerwalls@gmail.com>
Backport of e8ab2bb83fc6d3c0f5d998d1a41ebaebacaa1a28 from main.
| -rw-r--r-- | docs/topics/signals.txt | 41 |
1 files changed, 26 insertions, 15 deletions
diff --git a/docs/topics/signals.txt b/docs/topics/signals.txt index 4d32c55a2b..0c353ba8bd 100644 --- a/docs/topics/signals.txt +++ b/docs/topics/signals.txt @@ -172,8 +172,8 @@ Now, our ``my_callback`` function will be called each time a request finishes. The :meth:`~django.apps.AppConfig.ready` method may be executed more than once during testing, so you may want to :ref:`guard your signals from - duplication <preventing-duplicate-signals>`, especially if you're planning - to send them within tests. + duplication <preventing-duplicate-signals>` if your receiver is a bound + method on an instance that may be recreated. .. _connecting-to-specific-signals: @@ -211,20 +211,31 @@ each particular signal. Preventing duplicate signals ---------------------------- -In some circumstances, the code connecting receivers to signals may run -multiple times. This can cause your receiver function to be registered more -than once, and thus called as many times for a signal event. For example, the -:meth:`~django.apps.AppConfig.ready` method may be executed more than once -during testing. More generally, this occurs everywhere your project imports the -module where you define the signals, because signal registration runs as many -times as it is imported. +When ``dispatch_uid`` is not provided, Django identifies each receiver using +its Python object identity and registers it only once. For module-level +functions, static methods, and class methods, the identity is stable, so +connecting the same receiver more than once has no effect:: -If this behavior is problematic (such as when using signals to -send an email whenever a model is saved), pass a unique identifier as -the ``dispatch_uid`` argument to identify your receiver function. This -identifier will usually be a string, although any hashable object will -suffice. The end result is that your receiver function will only be -bound to the signal once for each unique ``dispatch_uid`` value:: + def my_handler(sender, **kwargs): ... + + + my_signal.connect(my_handler) # Running this code again is a no-op. + +Bound methods, which take a ``self`` argument, are different. Their identity +is tied to the specific instance, so connecting the same method from a new +instance registers it as an additional receiver:: + + def connect_signals(): + backend = Backend() + my_signal.connect(backend.my_handler) # A distinct receiver. + + + connect_signals() # Running this code again registers another receiver. + +When using a bound method as a receiver, multiple registrations can be +prevented by supplying a unique ``dispatch_uid``. This identifier will usually +be a string, although any hashable object will suffice. The receiver will only +be bound to the signal once for each unique ``dispatch_uid`` value:: from django.core.signals import request_finished |
