{"title":"Signaux","version":"3.1","locale":"fr","docname":"topics/signals","url":"/fr/3.1/topics/signals/","canonical":"https://djangodocs.dev/fr/3.1/topics/signals/","summary":"Django contient un « distributeur de signaux » qui permet aux applications découplées de pouvoir plus facilement être averties quand des actions se produisent…","html":"<span id=\"signals\"></span><h1>Signaux<a class=\"heading-anchor\" href=\"#module-django.dispatch\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h1>\n<p>Django contient un « distributeur de signaux » qui permet aux applications découplées de pouvoir plus facilement être averties quand des actions se produisent ailleurs dans un projet. En résumé, les signaux permettent à certains <em>expéditeurs</em> d’avertir un ensemble de <em>destinataires</em> qu’une action a eu lieu. Ils sont particulièrement utiles lorsque beaucoup de parties de code peuvent être intéressées aux mêmes événements.</p>\n<p>Django intègre un <a class=\"reference internal\" href=\"/fr/3.1/ref/signals/\"><span class=\"doc\">ensemble de signaux</span></a> permettant à du code client d’être averti par Django lui-même de certaines actions. Parmi ceux-ci, en voici quelques-uns bien utiles :</p>\n<ul>\n<li><p><a class=\"reference internal\" href=\"/fr/3.1/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> &amp;\n<a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.post_save\" title=\"django.db.models.signals.post_save\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.post_save</span></code></a></p>\n<p>Envoyés avant et après que la méthode <a class=\"reference internal\" href=\"/fr/3.1/ref/models/instances/#django.db.models.Model.save\" title=\"django.db.models.Model.save\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">save()</span></code></a> d’un modèle a été appelée.</p>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.pre_delete\" title=\"django.db.models.signals.pre_delete\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.pre_delete</span></code></a> &amp;\n<a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.post_delete\" title=\"django.db.models.signals.post_delete\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.post_delete</span></code></a></p>\n<p>Envoyés avant et après que la méthode  <a class=\"reference internal\" href=\"/fr/3.1/ref/models/instances/#django.db.models.Model.delete\" title=\"django.db.models.Model.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">delete()</span></code></a> d’un modèle ou que la méthode <a class=\"reference internal\" href=\"/fr/3.1/ref/models/querysets/#django.db.models.query.QuerySet.delete\" title=\"django.db.models.query.QuerySet.delete\"><code class=\"xref py py-meth docutils literal notranslate\"><span class=\"pre\">delete()</span></code></a> d’un <code class=\"docutils literal notranslate\"><span class=\"pre\">QuerySet</span></code> a été appelée.</p>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.db.models.signals.m2m_changed\" title=\"django.db.models.signals.m2m_changed\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.db.models.signals.m2m_changed</span></code></a></p>\n<p>Envoyé quand un champ <a class=\"reference internal\" href=\"/fr/3.1/ref/models/fields/#django.db.models.ManyToManyField\" title=\"django.db.models.ManyToManyField\"><code class=\"xref py py-class docutils literal notranslate\"><span class=\"pre\">ManyToManyField</span></code></a> d’un modèle a été modifié.</p>\n</li>\n<li><p><a class=\"reference internal\" href=\"/fr/3.1/ref/signals/#django.core.signals.request_started\" title=\"django.core.signals.request_started\"><code class=\"xref py py-data docutils literal notranslate\"><span class=\"pre\">django.core.signals.request_started</span></code></a> &amp;\n<a class=\"reference internal\" href=\"/fr/3.1/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\">django.core.signals.request_finished</span></code></a></p>\n<p>Envoyés lorsque Django démarre et termine une requête HTTP.</p>\n</li>\n</ul>\n<p>Consultez la <a class=\"reference internal\" href=\"/fr/3.1/ref/signals/\"><span class=\"doc\">documentation des signaux intégrés</span></a> pour une liste complète ainsi qu’une explication détaillée de chaque signal.</p>\n<p>Vous pouvez également <a class=\"reference internal\" href=\"#defining-and-sending-signals\">définir et envoyer vos propres signaux personnalisés</a> ; voir ci-dessous.</p>\n<section id=\"listening-to-signals\">\n<h2>Écoute de signaux<a class=\"heading-anchor\" href=\"#listening-to-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Pour recevoir un signal, inscrivez une fonction <em>réceptrice</em> en utilisant la méthode <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>. Cette fonction sera appelée au moment où le signal est envoyé. Toutes les fonctions réceptrices d’un signal sont appelées consécutivement dans l’ordre où elles ont été inscrites.</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"field-list simple\">\n<dt class=\"field-odd\">Paramètres<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>receiver</strong> – La fonction réceptrice qui sera connectée à ce signal. Voir <a class=\"reference internal\" href=\"#receiver-functions\"><span class=\"std std-ref\">Fonctions réceptrices</span></a> pour plus d’informations.</p></li>\n<li><p><strong>sender</strong> – Indique un expéditeur particulier duquel recevoir les signaux. Voir <a class=\"reference internal\" href=\"#connecting-to-specific-signals\"><span class=\"std std-ref\">Connexion aux signaux envoyés par des expéditeurs spécifiques</span></a> pour plus d’informations.</p></li>\n<li><p><strong>weak</strong> – Django stocke les gestionnaires de signaux comme référence faible par défaut. Cela signifie que si le récepteur est une fonction locale, il peut être purgé de la mémoire. Pour empêcher cela, indiquez <code class=\"docutils literal notranslate\"><span class=\"pre\">weak=False</span></code> lors de l’appel à la méthode <code class=\"docutils literal notranslate\"><span class=\"pre\">connect()</span></code> du signal.</p></li>\n<li><p><strong>dispatch_uid</strong> – Un identifiant unique pour un récepteur de signal afin d’éviter que certains signaux puissent être envoyés à double. Voir <a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">Prévention des signaux dupliqués</span></a> pour plus d’informations.</p></li>\n</ul>\n</dd>\n</dl>\n</dd></dl>\n\n<p>Voyons comment ça fonctionne en inscrivant un signal qui sera appelé à la fin de chaque requête HTTP. Nous allons nous connecter au signal <a class=\"reference internal\" href=\"/fr/3.1/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>.</p>\n<section id=\"receiver-functions\">\n<span id=\"id1\"></span><h3>Fonctions réceptrices<a class=\"heading-anchor\" href=\"#receiver-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Tout d’abord, nous devons définir une fonction réceptrice. Celle-ci peut être n’importe quelle fonction ou méthode Python :</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>Remarquez que la fonction accepte un paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code>, accompagné des paramètres nommés génériques (<code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code>) ; tous les gestionnaires de signal doivent accepter ces paramètres.</p>\n<p>Nous aborderons le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code> <a class=\"reference internal\" href=\"#connecting-to-signals-sent-by-specific-senders\">un peu plus loin</a>, mais commençons par examiner le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">**kwargs</span></code>. Tous les signaux envoient des paramètres nommés et peuvent changer ces paramètres nommés à tout instant. Dans le cas de <a class=\"reference internal\" href=\"/fr/3.1/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>, sa documentation indique qu’il n’envoie pas de paramètre, ce qui signifie que nous pourrions être tentés d’écrire notre fonction de signal comme <code class=\"docutils literal notranslate\"><span class=\"pre\">my_callback(sender)</span></code>.</p>\n<p>Ce serait une erreur. En fait, Django génère une exception dans ce cas, parce que l’on doit s’attendre à ce que de nouveaux paramètres soient ajoutés dans le temps et la fonction réceptrice doit être capable d’accepter ces nouveaux paramètres.</p>\n</section>\n<section id=\"connecting-receiver-functions\">\n<span id=\"id2\"></span><h3>Connexion des fonctions réceptrices<a class=\"heading-anchor\" href=\"#connecting-receiver-functions\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il y a deux façons de connecter une fonction réceptrice à un signal. Vous pouvez choisir l’option de la connexion manuelle :</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>L’autre possibilité est d’utiliser le décorateur <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>:</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><span class=\"sig-paren\">)</span><a class=\"heading-anchor\" href=\"#django.dispatch.receiver\"><span class=\"visually-hidden\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd><dl class=\"field-list simple\">\n<dt class=\"field-odd\">Paramètres<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><p><strong>signal</strong> – Un signal ou une liste de signaux auxquels connecter la fonction.</p>\n</dd>\n</dl>\n</dd></dl>\n\n<p>Voici comment faire la connexion avec le décorateur :</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<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>À partir de cet instant, la fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">my_callback</span></code> sera appelée chaque fois qu’une requête se termine.</p>\n<aside class=\"admonition-where-should-this-code-live admonition\">\n<p class=\"admonition-title\">À quel endroit ce code devrait-il se trouver ?</p>\n<p>Strictement parlant, le code du signal et le code d’inscription peuvent se trouver n’importe où, même s’il est recommandé d’éviter le module racine de l’application et son module <code class=\"docutils literal notranslate\"><span class=\"pre\">models</span></code> pour minimiser les effets de bord de l’importation du code.</p>\n<p>En pratique, les gestionnaires de signaux sont généralement définis dans un sous-module <code class=\"docutils literal notranslate\"><span class=\"pre\">signals</span></code> de l’application correspondante. Les récepteurs de signaux sont connectés dans la méthode <a class=\"reference internal\" href=\"/fr/3.1/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> de la classe de configuration de l’application. Si vous utilisez le décorateur <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>, importez le sous-module <code class=\"docutils literal notranslate\"><span class=\"pre\">signals</span></code> à l’intérieur de <a class=\"reference internal\" href=\"/fr/3.1/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>.</p>\n</aside>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">Note</p>\n<p>Il est possible que la méthode <a class=\"reference internal\" href=\"/fr/3.1/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> soit exécutée plus d’une fois durant les tests. Par conséquent, il est préférable d”<a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">empêcher la duplication des signaux</span></a>, particulièrement si vous pensez les exploiter dans les tests.</p>\n</aside>\n</section>\n<section id=\"connecting-to-signals-sent-by-specific-senders\">\n<span id=\"connecting-to-specific-signals\"></span><h3>Connexion aux signaux envoyés par des expéditeurs spécifiques<a class=\"heading-anchor\" href=\"#connecting-to-signals-sent-by-specific-senders\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Certains signaux sont envoyés de nombreuses fois, mais vous n’êtes pas toujours intéressé à tous les recevoir. Par exemple, considérez le signal <a class=\"reference internal\" href=\"/fr/3.1/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> envoyé avant chaque enregistrement de modèle. La plupart du temps, vous n’avez pas besoin de savoir quand <em>chaque</em> modèle est enregistré, mais seulement pour un modèle <em>spécifique</em>.</p>\n<p>Dans ces situations, vous pouvez inscrire une fonction pour qu’elle ne reçoive les signaux que de certains expéditeurs. Dans le cas de <a class=\"reference internal\" href=\"/fr/3.1/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>, l’expéditeur sera la classe du modèle en cours d’enregistrement, il est donc possible d’indiquer que vous ne voulez recevoir que les signaux envoyés par certains modèles :</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>\n    <span class=\"o\">...</span>\n</code></pre></div>\n<p>La fonction <code class=\"docutils literal notranslate\"><span class=\"pre\">my_handler</span></code> ne sera appelée que lors de l’enregistrement d’une instance de <code class=\"docutils literal notranslate\"><span class=\"pre\">MyModel</span></code>.</p>\n<p>Différents signaux utilisent différents objets comme expéditeurs ; il s’agit de consulter la <a class=\"reference internal\" href=\"/fr/3.1/ref/signals/\"><span class=\"doc\">documentation des signaux intégrés</span></a> pour plus de détails sur chaque signal.</p>\n</section>\n<section id=\"preventing-duplicate-signals\">\n<span id=\"id3\"></span><h3>Prévention des signaux dupliqués<a class=\"heading-anchor\" href=\"#preventing-duplicate-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Dans certaines circonstances, le code faisant la connexion entre les récepteurs et les signaux peut être exécuté à plusieurs reprises. En conséquence, la fonction de réception peut être inscrite plus d’une fois et être ensuite appelée plusieurs fois pour un même événement de signal. Par exemple, la méthode <a class=\"reference internal\" href=\"/fr/3.1/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>  peut être exécutée plus d’une fois pendant l’exécution des tests. Plus généralement, ceci se produit à chaque fois que votre projet importe le module où les signaux sont définis, car l’enregistrement d’un signal se produit autant de fois qu’il est importé.</p>\n<p>Si ce comportement est problématique (par exemple quand des signaux sont utilisés pour envoyer des courriels quand un modèle est enregistré), indiquez un identifiant unique dans le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code> pour identifier votre fonction réceptrice. Il s’agit généralement d’une chaîne de caractères, même si n’importe quel objet hachable peut faire l’affaire. En conséquence, la fonction réceptrice ne sera inscrite au signal qu’une seule fois par valeur unique de <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</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=\"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<h2>Définition et envoi de signaux<a class=\"heading-anchor\" href=\"#defining-and-sending-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h2>\n<p>Les applications peuvent profiter de l’infrastructure des signaux et fournir leurs propres signaux.</p>\n<aside class=\"admonition-when-to-use-custom-signals admonition\">\n<p class=\"admonition-title\">Quand utiliser des signaux personnalisés</p>\n<p>Les signaux sont des appels de fonctions implicites qui compliquent le débogage. Si l’expéditeur et le destinataire de votre signal personnalisé sont tous deux dans votre projet, il est alors préférable d’utiliser un appel de fonction explicite.</p>\n</aside>\n<section id=\"defining-signals\">\n<h3>Définition de signaux<a class=\"heading-anchor\" href=\"#defining-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Tous les signaux sont des instances de <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>.</p>\n<p>Par exemple :</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>Ceci déclare un signal <code class=\"docutils literal notranslate\"><span class=\"pre\">pizza_done</span></code>.</p>\n</section>\n<section id=\"sending-signals\">\n<h3>Envoi de signaux<a class=\"heading-anchor\" href=\"#sending-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</span><span aria-hidden=\"true\">#</span></a></h3>\n<p>Il y a deux façons d’envoyer des signaux dans 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\">Lien vers cette définition</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour envoyer un signal, appelez <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> (tous les signaux intégrés l’utilisent) ou <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>. Vous devez indiquer le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">sender</span></code> (qui est une classe la plupart du temps) et vous pouvez ajouter autant de paramètres nommés que vous le souhaitez.</p>\n<p>Par exemple, voici comment envoyer notre signal <code class=\"docutils literal notranslate\"><span class=\"pre\">pizza_done</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\">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>Aussi bien <code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> que <code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code> renvoient uns liste de paires de tuples <code class=\"docutils literal notranslate\"><span class=\"pre\">[(récepteur,</span> <span class=\"pre\">réponse),</span> <span class=\"pre\">...</span> <span class=\"pre\">]</span></code> correspondant à la liste des fonctions réceptrices appelées et la valeur de leur réponse.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> diffère de <code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code> par la manière dont les exceptions générées par les fonctions réceptrices sont traitées. <code class=\"docutils literal notranslate\"><span class=\"pre\">send()</span></code> n’intercepte <em>aucune</em> exception générée par les récepteurs ; elle laisse simplement les erreurs se propager. Il est donc possible que certains récepteurs ne soient pas notifiés par le signal en cas d’erreur.</p>\n<p><code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code> intercepte toutes les erreurs héritant de la classe <code class=\"docutils literal notranslate\"><span class=\"pre\">Exception</span></code> de Python et s’assure que tous les récepteurs soient notifiés par le signal. Si une erreur survient, l’instance d’erreur est renvoyée dans le tuple correspondant au récepteur qui a généré l’erreur.</p>\n<p>Les traces de débogage sont présentes dans l’attribut <code class=\"docutils literal notranslate\"><span class=\"pre\">__traceback__</span></code> des erreurs renvoyées lors des appels à <code class=\"docutils literal notranslate\"><span class=\"pre\">send_robust()</span></code>.</p>\n</section>\n</section>\n<section id=\"disconnecting-signals\">\n<h2>Déconnexion des signaux<a class=\"heading-anchor\" href=\"#disconnecting-signals\"><span class=\"visually-hidden\">Lien vers cette rubrique</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\">Lien vers cette définition</span><span aria-hidden=\"true\">#</span></a></dt>\n<dd></dd></dl>\n\n<p>Pour déconnecter un récepteur d’un signal, appelez <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>. Les paramètres sont identiques à ceux décrits pour <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>. La méthode renvoie <code class=\"docutils literal notranslate\"><span class=\"pre\">True</span></code> si un récepteur a été déconnecté, sinon <code class=\"docutils literal notranslate\"><span class=\"pre\">False</span></code>.</p>\n<p>Le paramètre <code class=\"docutils literal notranslate\"><span class=\"pre\">receiver</span></code> indique le récepteur inscrit qu’il s’agit de déconnecter. Il peut valoir <code class=\"docutils literal notranslate\"><span class=\"pre\">None</span></code> si <code class=\"docutils literal notranslate\"><span class=\"pre\">dispatch_uid</span></code> est utilisé pour identifier le récepteur.</p>\n</section>","rootId":"module-django.dispatch","toc":[{"title":"Écoute de signaux","anchor":"listening-to-signals","children":[{"title":"Fonctions réceptrices","anchor":"receiver-functions","children":[]},{"title":"Connexion des fonctions réceptrices","anchor":"connecting-receiver-functions","children":[]},{"title":"Connexion aux signaux envoyés par des expéditeurs spécifiques","anchor":"connecting-to-signals-sent-by-specific-senders","children":[]},{"title":"Prévention des signaux dupliqués","anchor":"preventing-duplicate-signals","children":[]}]},{"title":"Définition et envoi de signaux","anchor":"defining-and-sending-signals","children":[{"title":"Définition de signaux","anchor":"defining-signals","children":[]},{"title":"Envoi de signaux","anchor":"sending-signals","children":[]}]},{"title":"Déconnexion des signaux","anchor":"disconnecting-signals","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Utilisation de Django","url":"/fr/3.1/topics/"}],"prev":{"docname":"topics/settings","title":"Les réglages de Django","url":"/fr/3.1/topics/settings/"},"next":{"docname":"topics/checks","title":"Infrastructure de contrôle du système","url":"/fr/3.1/topics/checks/"},"formats":{"html":"/fr/3.1/topics/signals/","markdown":"/fr/3.1/topics/signals.md","json":"/fr/3.1/topics/signals.json"},"source":"https://github.com/django/django/blob/stable/3.1.x/docs/topics/signals.txt","official":"https://docs.djangoproject.com/fr/3.1/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","zh-hans","fr","ja","id","pt-br","ko","es","el","pl"]}