{"title":"Señales","version":"6.0","locale":"es","docname":"topics/signals","url":"/es/6.0/topics/signals/","canonical":"https://djangodocs.dev/es/6.0/topics/signals/","summary":"Django includes a «signal dispatcher» which helps decoupled applications get notified when actions occur elsewhere in the framework. In a nutshell, signals allow…","html":"<span id=\"signals\"></span><h1>Señales<a class=\"heading-anchor\" href=\"#module-django.dispatch\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django includes a «signal dispatcher» which helps decoupled applications get\nnotified when actions occur elsewhere in the framework. In a nutshell, signals\nallow certain <em>senders</em> to notify a set of <em>receivers</em> that some action has\ntaken place. They’re especially useful when many pieces of code may be\ninterested in the same events.</p>\n<p>For example, a third-party app can register to be notified of settings\nchanges:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.apps</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">AppConfig</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">setting_changed</span>\n\n\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_callback</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Setting changed!&quot;</span><span class=\"p\">)</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyAppConfig</span><span class=\"p\">(</span><span class=\"n\">AppConfig</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">ready</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"n\">setting_changed</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">my_callback</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Django’s <a class=\"reference internal\" href=\"/es/6.0/ref/signals/\"><span class=\"doc\">built-in signals</span></a> let user code get notified of\ncertain actions.</p>\n<p>You can also define and send your own custom signals. See\n<a class=\"reference internal\" href=\"#defining-and-sending-signals\"><span class=\"std std-ref\">Defining and sending signals</span></a> below.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Advertencia</p>\n<p>Signals give the appearance of loose coupling, but they can quickly lead to\ncode that is hard to understand, adjust and debug.</p>\n<p>Where possible you should opt for directly calling the handling code,\nrather than dispatching via a signal.</p>\n</aside>\n<section id=\"listening-to-signals\">\n<h2>Listening to signals<a class=\"heading-anchor\" href=\"#listening-to-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>To receive a signal, register a <em>receiver</em> function using the\n<a class=\"reference internal\" href=\"#django.dispatch.Signal.connect\" title=\"django.dispatch.Signal.connect\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.connect()</span></code></a> method. The receiver function is called when the signal\nis sent. All of the signal’s receiver functions are called one at a time, in\nthe order they were registered.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.connect\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">connect</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">receiver</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">weak</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">True</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">dispatch_uid</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.connect\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parámetros<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>receiver</strong> – The callback function which will be connected to this\nsignal. See <a class=\"reference internal\" href=\"#receiver-functions\"><span class=\"std std-ref\">Receiver functions</span></a> for more information.</p></li>\n<li><p><strong>sender</strong> – Specifies a particular sender to receive signals from. See\n<a class=\"reference internal\" href=\"#connecting-to-specific-signals\"><span class=\"std std-ref\">Connecting to signals sent by specific senders</span></a> for more information.</p></li>\n<li><p><strong>weak</strong> – Django stores signal handlers as weak references by\ndefault. Thus, if your receiver is a local function, it may be\ngarbage collected. To prevent this, pass <code class=\"docutils literal notranslate\"><span class=\"pre\">weak=False</span></code> when you call\nthe signal’s <code class=\"docutils literal notranslate\"><span class=\"pre\">connect()</span></code> method.</p></li>\n<li><p><strong>dispatch_uid</strong> – A unique identifier for a signal receiver in cases\nwhere duplicate signals may be sent. See\n<a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">Preventing duplicate signals</span></a> for more information.</p></li>\n</ul>\n</dd>\n</dl>\n</dd></dl>\n\n<p>Let’s see how this works by registering a signal that\ngets called after each HTTP request is finished. We’ll be connecting to the\n<a class=\"reference internal\" href=\"/es/6.0/ref/signals/#django.core.signals.request_finished\" title=\"django.core.signals.request_finished\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">request_finished</span></code></a> signal.</p>\n<section id=\"receiver-functions\">\n<span id=\"id1\"></span><h3>Receiver functions<a class=\"heading-anchor\" href=\"#receiver-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>First, we need to define a receiver function. A receiver can be any Python\nfunction or method:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_callback</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Request finished!&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Notice that the function takes a <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code> argument, along with wildcard\nkeyword arguments (<code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code>); all signal handlers must take these\narguments.</p>\n<p>We’ll look at senders <a class=\"reference internal\" href=\"#connecting-to-specific-signals\"><span class=\"std std-ref\">a bit later</span></a>, but\nright now look at the <code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code> argument. All signals send keyword\narguments, and may change those keyword arguments at any time. In the case of\n<a class=\"reference internal\" href=\"/es/6.0/ref/signals/#django.core.signals.request_finished\" title=\"django.core.signals.request_finished\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">request_finished</span></code></a>, it’s documented as sending no\narguments, which means we might be tempted to write our signal handling as\n<code class=\"docutils literal notranslate\"><span class=\"pre\">my_callback(sender)</span></code>.</p>\n<p>This would be wrong – in fact, Django will throw an error if you do so. That’s\nbecause at any point arguments could get added to the signal and your receiver\nmust be able to handle those new arguments.</p>\n<p>Receivers may also be asynchronous functions, with the same signature but\ndeclared using <code class=\"docutils literal notranslate\"><span class=\"pre\">async</span> <span class=\"pre\">def</span></code>:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_callback</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"k\">await</span> <span class=\"n\">asyncio</span><span class=\"o\">.</span><span class=\"n\">sleep</span><span class=\"p\">(</span><span class=\"mi\">5</span><span class=\"p\">)</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Request finished!&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Signals can be sent either synchronously or asynchronously, and receivers will\nautomatically be adapted to the correct call-style. See <a class=\"reference internal\" href=\"#sending-signals\"><span class=\"std std-ref\">sending signals</span></a> for more information.</p>\n</section>\n<section id=\"connecting-receiver-functions\">\n<span id=\"id2\"></span><h3>Connecting receiver functions<a class=\"heading-anchor\" href=\"#connecting-receiver-functions\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>There are two ways you can connect a receiver to a signal. You can take the\nmanual connect route:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">request_finished</span>\n\n<span class=\"n\">request_finished</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">my_callback</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Alternatively, you can use a <a class=\"reference internal\" href=\"#django.dispatch.receiver\" title=\"django.dispatch.receiver\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">receiver()</span></code></a> decorator:</p>\n<dl class=\"py function\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.receiver\">\n<span class=\"sig-name descname\"><span class=\"pre\">receiver</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">signal</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.receiver\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"field-list simple\">\n<dt class=\"field-odd\">Parámetros<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>signal</strong> – A signal or a list of signals to connect a function to.</p></li>\n<li><p><strong>kwargs</strong> – Wildcard keyword arguments to pass to a\n<a class=\"reference internal\" href=\"#receiver-functions\"><span class=\"std std-ref\">function</span></a>.</p></li>\n</ul>\n</dd>\n</dl>\n</dd></dl>\n\n<p>Here’s how you connect with the decorator:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">request_finished</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.dispatch</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">receiver</span>\n\n\n<span class=\"nd\">@receiver</span><span class=\"p\">(</span><span class=\"n\">request_finished</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_callback</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span>\n    <span class=\"nb\">print</span><span class=\"p\">(</span><span class=\"s2\">&quot;Request finished!&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n<p>Now, our <code class=\"docutils literal notranslate\"><span class=\"pre\">my_callback</span></code> function will be called each time a request finishes.</p>\n<aside class=\"admonition-where-should-this-code-live admonition\">\n<p class=\"admonition-title\">¿Dónde debería estar este código?</p>\n<p>Strictly speaking, signal handling and registration code can live anywhere\nyou like, although it’s recommended to avoid the application’s root module\nand its <code class=\"docutils literal notranslate\"><span class=\"pre\">models</span></code> module to minimize side-effects of importing code.</p>\n<p>In practice, signal handlers are usually defined in a <code class=\"docutils literal notranslate\"><span class=\"pre\">signals</span></code>\nsubmodule of the application they relate to. Signal receivers are\nconnected in the <a class=\"reference internal\" href=\"/es/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">ready()</span></code></a> method of your\napplication <a class=\"reference internal\" href=\"/es/6.0/ref/applications/#configuring-applications-ref\"><span class=\"std std-ref\">configuration class</span></a>. If\nyou’re using the <a class=\"reference internal\" href=\"#django.dispatch.receiver\" title=\"django.dispatch.receiver\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">receiver()</span></code></a> decorator, import the <code class=\"docutils literal notranslate\"><span class=\"pre\">signals</span></code>\nsubmodule inside <a class=\"reference internal\" href=\"/es/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">ready()</span></code></a>, this will implicitly\nconnect signal handlers:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.apps</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">AppConfig</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">request_finished</span>\n\n\n<span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">MyAppConfig</span><span class=\"p\">(</span><span class=\"n\">AppConfig</span><span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">ready</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        <span class=\"c1\"># Implicitly connect signal handlers decorated with @receiver.</span>\n        <span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">.</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">signals</span>\n\n        <span class=\"c1\"># Explicitly connect a signal handler.</span>\n        <span class=\"n\">request_finished</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">signals</span><span class=\"o\">.</span><span class=\"n\">my_callback</span><span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Nota</p>\n<p>The <a class=\"reference internal\" href=\"/es/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">ready()</span></code></a> method may be executed more than\nonce during testing, so you may want to <a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">guard your signals from\nduplication</span></a> if your receiver is a bound\nmethod on an instance that may be recreated.</p>\n</aside>\n</section>\n<section id=\"connecting-to-signals-sent-by-specific-senders\">\n<span id=\"connecting-to-specific-signals\"></span><h3>Connecting to signals sent by specific senders<a class=\"heading-anchor\" href=\"#connecting-to-signals-sent-by-specific-senders\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Some signals get sent many times, but you’ll only be interested in receiving a\ncertain subset of those signals. For example, consider the\n<a class=\"reference internal\" href=\"/es/6.0/ref/signals/#django.db.models.signals.pre_save\" title=\"django.db.models.signals.pre_save\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.pre_save</span></code></a> signal sent before a model gets\nsaved. Most of the time, you don’t need to know when <em>any</em> model gets saved –\njust when one <em>specific</em> model is saved.</p>\n<p>In these cases, you can register to receive signals sent only by particular\nsenders. In the case of <a class=\"reference internal\" href=\"/es/6.0/ref/signals/#django.db.models.signals.pre_save\" title=\"django.db.models.signals.pre_save\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.pre_save</span></code></a>, the sender\nwill be the model class being saved, so you can indicate that you only want\nsignals sent by some model:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.db.models.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">pre_save</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.dispatch</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">receiver</span>\n<span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">myapp.models</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">MyModel</span>\n\n\n<span class=\"nd\">@receiver</span><span class=\"p\">(</span><span class=\"n\">pre_save</span><span class=\"p\">,</span> <span class=\"n\">sender</span><span class=\"o\">=</span><span class=\"n\">MyModel</span><span class=\"p\">)</span>\n<span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_handler</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">my_handler</span></code> function will only be called when an instance of <code class=\"docutils literal notranslate\"><span class=\"pre\">MyModel</span></code>\nis saved.</p>\n<p>Different signals use different objects as their senders; you’ll need to\nconsult the <a class=\"reference internal\" href=\"/es/6.0/ref/signals/\"><span class=\"doc\">built-in signal documentation</span></a> for details of\neach particular signal.</p>\n</section>\n<section id=\"preventing-duplicate-signals\">\n<span id=\"id3\"></span><h3>Preventing duplicate signals<a class=\"heading-anchor\" href=\"#preventing-duplicate-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>When <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code> is not provided, Django identifies each receiver using\nits Python object identity and registers it only once. For module-level\nfunctions, static methods, and class methods, the identity is stable, so\nconnecting the same receiver more than once has no effect:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">my_handler</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"p\">,</span> <span class=\"o\">**</span><span class=\"n\">kwargs</span><span class=\"p\">):</span> <span class=\"o\">...</span>\n\n\n<span class=\"n\">my_signal</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">my_handler</span><span class=\"p\">)</span>  <span class=\"c1\"># Running this code again is a no-op.</span>\n</code></pre></div>\n<p>Bound methods, which take a <code class=\"docutils literal notranslate\"><span class=\"pre\">self</span></code> argument, are different. Their identity\nis tied to the specific instance, so connecting the same method from a new\ninstance registers it as an additional receiver:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">connect_signals</span><span class=\"p\">():</span>\n    <span class=\"n\">backend</span> <span class=\"o\">=</span> <span class=\"n\">Backend</span><span class=\"p\">()</span>\n    <span class=\"n\">my_signal</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">backend</span><span class=\"o\">.</span><span class=\"n\">my_handler</span><span class=\"p\">)</span>  <span class=\"c1\"># A distinct receiver.</span>\n\n\n<span class=\"n\">connect_signals</span><span class=\"p\">()</span>  <span class=\"c1\"># Running this code again registers another receiver.</span>\n</code></pre></div>\n<p>When using a bound method as a receiver, multiple registrations can be\nprevented by supplying a unique <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code>. This identifier will usually\nbe a string, although any hashable object will suffice. The receiver will only\nbe bound to the signal once for each unique <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code> value:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">from</span><span class=\"w\"> </span><span class=\"nn\">django.core.signals</span><span class=\"w\"> </span><span class=\"kn\">import</span> <span class=\"n\">request_finished</span>\n\n<span class=\"n\">request_finished</span><span class=\"o\">.</span><span class=\"n\">connect</span><span class=\"p\">(</span><span class=\"n\">my_callback</span><span class=\"p\">,</span> <span class=\"n\">dispatch_uid</span><span class=\"o\">=</span><span class=\"s2\">&quot;my_unique_identifier&quot;</span><span class=\"p\">)</span>\n</code></pre></div>\n</section>\n</section>\n<section id=\"defining-and-sending-signals\">\n<span id=\"id4\"></span><h2>Defining and sending signals<a class=\"heading-anchor\" href=\"#defining-and-sending-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Your applications can take advantage of the signal infrastructure and provide\nits own signals.</p>\n<aside class=\"admonition-when-to-use-custom-signals admonition\">\n<p class=\"admonition-title\">When to use custom signals</p>\n<p>Signals are implicit function calls which make debugging harder. If the\nsender and receiver of your custom signal are both within your project,\nyou’re better off using an explicit function call.</p>\n</aside>\n<section id=\"defining-signals\">\n<h3>Defining signals<a class=\"heading-anchor\" href=\"#defining-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<dl class=\"py class\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal\">\n<em class=\"property\"><span class=\"k\"><span class=\"pre\">class</span></span><span class=\"w\"> </span></em><span class=\"sig-name descname\"><span class=\"pre\">Signal</span></span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>All signals are <a class=\"reference internal\" href=\"#django.dispatch.Signal\" title=\"django.dispatch.Signal\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">django.dispatch.Signal</span></code></a> instances.</p>\n<p>Por ejemplo:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"kn\">import</span><span class=\"w\"> </span><span class=\"nn\">django.dispatch</span>\n\n<span class=\"n\">pizza_done</span> <span class=\"o\">=</span> <span class=\"n\">django</span><span class=\"o\">.</span><span class=\"n\">dispatch</span><span class=\"o\">.</span><span class=\"n\">Signal</span><span class=\"p\">()</span>\n</code></pre></div>\n<p>This declares a <code class=\"docutils literal notranslate\"><span class=\"pre\">pizza_done</span></code> signal.</p>\n</section>\n<section id=\"sending-signals\">\n<span id=\"id5\"></span><h3>Sending signals<a class=\"heading-anchor\" href=\"#sending-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>There are two ways to send signals synchronously in Django.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.send\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">send</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.send\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.send_robust\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">send_robust</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.send_robust\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Signals may also be sent asynchronously.</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.asend\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">asend</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.asend\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.asend_robust\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">asend_robust</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span></em>, <em class=\"sig-param\"><span class=\"o\"><span class=\"pre\">**</span></span><span class=\"n\"><span class=\"pre\">kwargs</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.asend_robust\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>To send a signal, call either <a class=\"reference internal\" href=\"#django.dispatch.Signal.send\" title=\"django.dispatch.Signal.send\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.send()</span></code></a>, <a class=\"reference internal\" href=\"#django.dispatch.Signal.send_robust\" title=\"django.dispatch.Signal.send_robust\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.send_robust()</span></code></a>,\n<a class=\"reference internal\" href=\"#django.dispatch.Signal.asend\" title=\"django.dispatch.Signal.asend\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">await</span> <span class=\"pre\">Signal.asend()</span></code></a>, or\n<a class=\"reference internal\" href=\"#django.dispatch.Signal.asend_robust\" title=\"django.dispatch.Signal.asend_robust\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">await</span> <span class=\"pre\">Signal.asend_robust()</span></code></a>. You must provide the\n<code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code> argument (which is a class most of the time) and may provide as many\nother keyword arguments as you like.</p>\n<p>For example, here’s how sending our <code class=\"docutils literal notranslate\"><span class=\"pre\">pizza_done</span></code> signal might look:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">class</span><span class=\"w\"> </span><span class=\"nc\">PizzaStore</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">send_pizza</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">toppings</span><span class=\"p\">,</span> <span class=\"n\">size</span><span class=\"p\">):</span>\n        <span class=\"n\">pizza_done</span><span class=\"o\">.</span><span class=\"n\">send</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">,</span> <span class=\"n\">toppings</span><span class=\"o\">=</span><span class=\"n\">toppings</span><span class=\"p\">,</span> <span class=\"n\">size</span><span class=\"o\">=</span><span class=\"n\">size</span><span class=\"p\">)</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>All four methods return a list of tuple pairs <code class=\"docutils literal notranslate\"><span class=\"pre\">[(receiver,</span> <span class=\"pre\">response),</span> <span class=\"pre\">...]</span></code>,\nrepresenting the list of called receiver functions and their response values.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> differs from <code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code> in how exceptions raised by receiver\nfunctions are handled. <code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> does <em>not</em> catch any exceptions raised by\nreceivers; it simply allows errors to propagate. Thus not all receivers may\nbe notified of a signal in the face of an error.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code> catches all errors derived from Python’s <code class=\"docutils literal notranslate\"><span class=\"pre\">Exception</span></code> class,\nand ensures all receivers are notified of the signal. If an error occurs, the\nerror instance is returned in the tuple pair for the receiver that raised the\nerror.</p>\n<p>The tracebacks are present on the <code class=\"docutils literal notranslate\"><span class=\"pre\">__traceback__</span></code> attribute of the errors\nreturned when calling <code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code>.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">asend()</span></code> is similar to <code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code>, but it is a coroutine that must be\nawaited:</p>\n<div class=\"code-block\" data-language=\"default\"><div class=\"code-block-toolbar\"><span class=\"code-block-language\">Code</span><button type=\"button\" class=\"copy-button\" data-copy hidden><span class=\"copy-button-label\">Copy</span></button></div><pre role=\"group\" tabindex=\"0\" aria-label=\"Code code\"><code><span class=\"k\">async</span> <span class=\"k\">def</span><span class=\"w\"> </span><span class=\"nf\">asend_pizza</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> <span class=\"n\">toppings</span><span class=\"p\">,</span> <span class=\"n\">size</span><span class=\"p\">):</span>\n    <span class=\"k\">await</span> <span class=\"n\">pizza_done</span><span class=\"o\">.</span><span class=\"n\">asend</span><span class=\"p\">(</span><span class=\"n\">sender</span><span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">,</span> <span class=\"n\">toppings</span><span class=\"o\">=</span><span class=\"n\">toppings</span><span class=\"p\">,</span> <span class=\"n\">size</span><span class=\"o\">=</span><span class=\"n\">size</span><span class=\"p\">)</span>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>Whether synchronous or asynchronous, receivers will be correctly adapted to\nwhether <code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">asend()</span></code> is used. Synchronous receivers will be\ncalled using <a class=\"reference internal\" href=\"/es/6.0/topics/async/#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">sync_to_async()</span></code></a> when invoked via <code class=\"docutils literal notranslate\"><span class=\"pre\">asend()</span></code>. Asynchronous\nreceivers will be called using <a class=\"reference internal\" href=\"/es/6.0/topics/async/#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\"><span class=\"pre\">async_to_sync()</span></code></a> when invoked via\n<code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code>. Similar to the <a class=\"reference internal\" href=\"/es/6.0/topics/async/#async-performance\"><span class=\"std std-ref\">case for middleware</span></a>,\nthere is a small performance cost to adapting receivers in this way. Note that\nin order to reduce the number of sync/async calling-style switches within a\n<code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> or <code class=\"docutils literal notranslate\"><span class=\"pre\">asend()</span></code> call, the receivers are grouped by whether or not\nthey are async before being called. This means that an asynchronous receiver\nregistered before a synchronous receiver may be executed after the synchronous\nreceiver. In addition, async receivers are executed concurrently using\n<code class=\"docutils literal notranslate\"><span class=\"pre\">asyncio.gather()</span></code>.</p>\n<p>All built-in signals, except those in the async request-response cycle, are\ndispatched using <a class=\"reference internal\" href=\"#django.dispatch.Signal.send\" title=\"django.dispatch.Signal.send\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.send()</span></code></a>.</p>\n</section>\n</section>\n<section id=\"disconnecting-signals\">\n<h2>Disconnecting signals<a class=\"heading-anchor\" href=\"#disconnecting-signals\"><span class=\"visually-hidden\">Link to this heading</span><span aria-hidden=\"true\">#</span></a></h2>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.disconnect\">\n<span class=\"sig-prename descclassname\"><span class=\"pre\">Signal.</span></span><span class=\"sig-name descname\"><span class=\"pre\">disconnect</span></span><span class=\"sig-paren\">(</span><em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">receiver</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">sender</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em>, <em class=\"sig-param\"><span class=\"n\"><span class=\"pre\">dispatch_uid</span></span><span class=\"o\"><span class=\"pre\">=</span></span><span class=\"default_value\"><span class=\"pre\">None</span></span></em><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.Signal.disconnect\"><span class=\"visually-hidden\">Link to this definition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>To disconnect a receiver from a signal, call <a class=\"reference internal\" href=\"#django.dispatch.Signal.disconnect\" title=\"django.dispatch.Signal.disconnect\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.disconnect()</span></code></a>. The\narguments are as described in <a class=\"reference internal\" href=\"#django.dispatch.Signal.connect\" title=\"django.dispatch.Signal.connect\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">Signal.connect()</span></code></a>. The method returns\n<code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> if a receiver was disconnected and <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code> if not. When <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code>\nis passed as a lazy reference to <code class=\"docutils literal notranslate\"><span class=\"pre\">&lt;app</span> <span class=\"pre\">label&gt;.&lt;model&gt;</span></code>, this method always\nreturns <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code>.</p>\n<p>The <code class=\"docutils literal notranslate\"><span class=\"pre\">receiver</span></code> argument indicates the registered receiver to disconnect. It\nmay be <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> if <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code> is used to identify the receiver.</p>\n</section>","rootId":"module-django.dispatch","toc":[{"title":"Listening to signals","anchor":"listening-to-signals","children":[{"title":"Receiver functions","anchor":"receiver-functions","children":[]},{"title":"Connecting receiver functions","anchor":"connecting-receiver-functions","children":[]},{"title":"Connecting to signals sent by specific senders","anchor":"connecting-to-signals-sent-by-specific-senders","children":[]},{"title":"Preventing duplicate signals","anchor":"preventing-duplicate-signals","children":[]}]},{"title":"Defining and sending signals","anchor":"defining-and-sending-signals","children":[{"title":"Defining signals","anchor":"defining-signals","children":[]},{"title":"Sending signals","anchor":"sending-signals","children":[]}]},{"title":"Disconnecting signals","anchor":"disconnecting-signals","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Using Django","url":"/es/6.0/topics/"}],"prev":{"docname":"topics/settings","title":"Django settings","url":"/es/6.0/topics/settings/"},"next":{"docname":"topics/checks","title":"Framework de comprobación de sistema","url":"/es/6.0/topics/checks/"},"formats":{"html":"/es/6.0/topics/signals/","markdown":"/es/6.0/topics/signals.md","json":"/es/6.0/topics/signals.json"},"source":"https://github.com/django/django/blob/stable/6.0.x/docs/topics/signals.txt","official":"https://docs.djangoproject.com/es/6.0/topics/signals/","inVersions":["6.1","6.0","5.2","5.1","5.0","4.2","4.1","4.0","3.2","3.1","3.0","2.2","2.1","2.0","1.11","1.10","1.9"],"inLocales":["en","sv","zh-hans","ga","fr","ja","id","it","pt-br","ko","es","el","pl"]}