{"title":"シグナル","version":"5.1","locale":"ja","docname":"topics/signals","url":"/ja/5.1/topics/signals/","canonical":"https://djangodocs.dev/ja/5.1/topics/signals/","summary":"Django には \"シグナルディスパッチャ\" があり、フレームワークの他の場所でアクションが発生したときに、ほかのアプリケーションが通知を受けるのを助けてくれます。","html":"<span id=\"signals\"></span><h1>シグナル<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 には &quot;シグナルディスパッチャ&quot; があり、フレームワークの他の場所でアクションが発生したときに、ほかのアプリケーションが通知を受けるのを助けてくれます。簡単に言うと、シグナルは特定の <em>送り手</em> が、あるアクションが発生したことを一連の <em>受け手</em> に通知できるようにします。特に、多くのコードが同じイベントに関連している場合に便利です。</p>\n<p>例えば、サードパーティのアプリを登録して、設定変更の通知を受けることができます:</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=\"nn\">django.apps</span> <span class=\"kn\">import</span> AppConfig\n<span class=\"kn\">from</span> <span class=\"nn\">django.core.signals</span> <span class=\"kn\">import</span> setting_changed\n\n\n<span class=\"k\">def</span> <span class=\"nf\">my_callback</span><span class=\"p\">(</span>sender<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<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=\"nc\">MyAppConfig</span><span class=\"p\">(</span>AppConfig<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">ready</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">):</span>\n        setting_changed<span class=\"o\">.</span>connect<span class=\"p\">(</span>my_callback<span class=\"p\">)</span>\n</code></pre></div>\n<p>Django の <a class=\"reference internal\" href=\"/ja/5.1/ref/signals/\"><span class=\"doc\">組み込みのシグナル</span></a> は、ユーザコードに特定のアクションを通知します。</p>\n<p>また、独自のカスタムシグナルを定義して送信することもできます。以下の <a class=\"reference internal\" href=\"#defining-and-sending-signals\"><span class=\"std std-ref\">シグナルの定義と送信</span></a> を参照してください。</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">警告</p>\n<p>シグナルは疎結合のように見えますが、すぐに理解や調整、デバッグが難しいコードにつながります。</p>\n<p>可能であれば、シグナルでディスパッチするのではなく、処理コードを直接呼び出すことを選ぶべきです。</p>\n</aside>\n<section id=\"listening-to-signals\">\n<h2>シグナルを待ち受ける<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>シグナルを受信するには、 <a class=\"reference internal\" href=\"#django.dispatch.Signal.connect\" title=\"django.dispatch.Signal.connect\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.connect()</code></a> メソッドを使って <em>receiver</em> 関数を登録します。シグナルが送信されると、レシーバ関数が呼び出されます。シグナルのすべてのレシーバ関数は、登録された順番に1つずつ呼び出されます。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.connect\">\n<span class=\"sig-prename descclassname\">Signal.</span><span class=\"sig-name descname\">connect</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">receiver</em>, <em class=\"sig-param\">sender<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">weak<span class=\"o\">=</span><span class=\"default_value\">True</span></em>, <em class=\"sig-param\">dispatch_uid<span class=\"o\">=</span><span class=\"default_value\">None</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\">パラメータ<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>receiver</strong> -- このシグナルに接続されるコールバック関数です。詳しくは <a class=\"reference internal\" href=\"#receiver-functions\"><span class=\"std std-ref\">レシーバ関数</span></a> を参照してください。</p></li>\n<li><p><strong>sender</strong> -- シグナルを受信する送信者を指定します。詳しくは <a class=\"reference internal\" href=\"#connecting-to-specific-signals\"><span class=\"std std-ref\">特定の送信者によって送られたシグナルに接続する</span></a> を参照してください。</p></li>\n<li><p><strong>weak</strong> -- Django はデフォルトでシグナルハンドラを弱い参照として保存します。従って、レシーバがローカル関数の場合、ガベージコレクションされる可能性 があります。これを防ぐには、シグナルの <code class=\"docutils literal notranslate\">connect()</code> メソッドを呼び出すときに <code class=\"docutils literal notranslate\">weak=False</code> を渡してください。</p></li>\n<li><p><strong>dispatch_uid</strong> -- シグナルが重複して送信される可能性がある場合の、シグナル受信機の一意な識別子。詳しくは <a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">重複したシグナルを防止する</span></a> を参照してください。</p></li>\n</ul>\n</dd>\n</dl>\n</dd></dl>\n\n<p>HTTP リクエストが終了するたびに呼び出されるシグナルを登録することで、この仕組みを見てみましょう。ここでは <a class=\"reference internal\" href=\"/ja/5.1/ref/signals/#django.core.signals.request_finished\" title=\"django.core.signals.request_finished\"><code class=\"xref py py-data docutils literal notranslate\">request_finished</code></a> シグナルに接続します。</p>\n<section id=\"receiver-functions\">\n<span id=\"id1\"></span><h3>レシーバ関数<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>まず、レシーバ関数を定義する必要があります。レシーバは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=\"nf\">my_callback</span><span class=\"p\">(</span>sender<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<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>この関数は <code class=\"docutils literal notranslate\">sender</code> 引数とワイルドカードキーワード引数 (<code class=\"docutils literal notranslate\">**kwargs</code>) を取ることに注意してください。すべてのシグナルハンドラはこれらの引数を取らなければなりません。</p>\n<p>送信者については <a class=\"reference internal\" href=\"#connecting-to-specific-signals\"><span class=\"std std-ref\">もう少し後で</span></a> 見るので、今は <code class=\"docutils literal notranslate\">**kwargs</code> 引数を見てください。すべてのシグナルはキーワード引数を送信し、いつでもそのキーワード引数を変更できます。 <a class=\"reference internal\" href=\"/ja/5.1/ref/signals/#django.core.signals.request_finished\" title=\"django.core.signals.request_finished\"><code class=\"xref py py-data docutils literal notranslate\">request_finished</code></a> の場合、引数を送らないようにドキュメント化されているので、シグナル処理を <code class=\"docutils literal notranslate\">my_callback(sender)</code> と書きたくなるかもしれません。</p>\n<p>これは間違いです。実際、そうすると Django はエラーを返します。というのも、シグナルに引数が追加される可能性があり、レシーバはその新しい引数を扱えなければならないからです。</p>\n<p>レシーバーは同じシグネチャーを持ち、<code class=\"docutils literal notranslate\">async def</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=\"nf\">my_callback</span><span class=\"p\">(</span>sender<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span>\n    <span class=\"k\">await</span> asyncio<span class=\"o\">.</span>sleep<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>シグナルは同期でも非同期でも送ることができ、受信側は自動的に正しいコールスタイルに合わせられます。詳細は <a class=\"reference internal\" href=\"#sending-signals\"><span class=\"std std-ref\">シグナルを送る</span></a> を参照してください。</p>\n<aside class=\"version-note version-changed\" data-version=\"5.0\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 5.0</p><p>非同期レシーバのサポートが追加されました。</p>\n</aside>\n</section>\n<section id=\"connecting-receiver-functions\">\n<span id=\"id2\"></span><h3>レシーバ関数に接続する<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>受信機を信号に接続する方法は2つあります。手動で接続する方法です:</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=\"nn\">django.core.signals</span> <span class=\"kn\">import</span> request_finished\n\nrequest_finished<span class=\"o\">.</span>connect<span class=\"p\">(</span>my_callback<span class=\"p\">)</span>\n</code></pre></div>\n<p>あるいは、 <a class=\"reference internal\" href=\"#django.dispatch.receiver\" title=\"django.dispatch.receiver\"><code class=\"xref py py-func docutils literal notranslate\">receiver()</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\">receiver</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">signal</em>, <em class=\"sig-param\"><span class=\"o\">**</span>kwargs</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\">パラメータ<span class=\"colon\">:</span></dt>\n<dd class=\"field-odd\"><ul class=\"simple\">\n<li><p><strong>signal</strong> -- 関数を接続するシグナルまたはシグナルのリスト。</p></li>\n<li><p><strong>kwargs</strong> -- <a class=\"reference internal\" href=\"#receiver-functions\"><span class=\"std std-ref\">関数</span></a> に渡すワイルドカードキーワード引数です。</p></li>\n</ul>\n</dd>\n</dl>\n</dd></dl>\n\n<p>下記がデコレーターとの繋げ方です:</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=\"nn\">django.core.signals</span> <span class=\"kn\">import</span> request_finished\n<span class=\"kn\">from</span> <span class=\"nn\">django.dispatch</span> <span class=\"kn\">import</span> receiver\n\n\n<span class=\"nd\">@receiver</span><span class=\"p\">(</span>request_finished<span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">my_callback</span><span class=\"p\">(</span>sender<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<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>これで、リクエストが終了するたびに <code class=\"docutils literal notranslate\">my_callback</code> 関数が呼ばれるようになります。</p>\n<aside class=\"admonition-where-should-this-code-live admonition\" role=\"note\">\n<p class=\"admonition-title\">コードはどこに置くの？</p>\n<p>厳密には、シグナル処理と登録のコードは好きな場所に置くことができますが、コードのインポートによる副作用を最小限にするために、アプリケーションのルートモジュールと <code class=\"docutils literal notranslate\">models</code> モジュールの置くのは避けることを推奨します。</p>\n<p>実際には、シグナルハンドラは通常、関連するアプリケーションの <code class=\"docutils literal notranslate\">signals</code> サブモジュールで定義されます。シグナルレシーバーはアプリケーションの  <a class=\"reference internal\" href=\"/ja/5.1/ref/applications/#configuring-applications-ref\"><span class=\"std std-ref\">configuration クラス</span></a> の <a class=\"reference internal\" href=\"/ja/5.1/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</code></a> メソッドで接続されます。 <a class=\"reference internal\" href=\"#django.dispatch.receiver\" title=\"django.dispatch.receiver\"><code class=\"xref py py-func docutils literal notranslate\">receiver()</code></a> デコレータを使っている場合は、 <a class=\"reference internal\" href=\"/ja/5.1/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</code></a> の中にある <code class=\"docutils literal notranslate\">signals</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=\"nn\">django.apps</span> <span class=\"kn\">import</span> AppConfig\n<span class=\"kn\">from</span> <span class=\"nn\">django.core.signals</span> <span class=\"kn\">import</span> request_finished\n\n\n<span class=\"k\">class</span> <span class=\"nc\">MyAppConfig</span><span class=\"p\">(</span>AppConfig<span class=\"p\">):</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</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=\"nn\">.</span> <span class=\"kn\">import</span> signals\n\n        <span class=\"c1\"># Explicitly connect a signal handler.</span>\n        request_finished<span class=\"o\">.</span>connect<span class=\"p\">(</span>signals<span class=\"o\">.</span>my_callback<span class=\"p\">)</span>\n</code></pre></div>\n</aside>\n<aside class=\"admonition admonition-note\" role=\"note\">\n<p class=\"admonition-title\">注釈</p>\n<p>テスト中に <a class=\"reference internal\" href=\"/ja/5.1/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</code></a> メソッドが複数回実行されることがあるため、特にテスト内でシグナルを送信する予定がある場合は、<a class=\"reference internal\" href=\"#preventing-duplicate-signals\"><span class=\"std std-ref\">シグナルの重複を防ぐ</span></a> ためにシグナルを保護することを検討するとよいでしょう。</p>\n</aside>\n</section>\n<section id=\"connecting-to-signals-sent-by-specific-senders\">\n<span id=\"connecting-to-specific-signals\"></span><h3>特定の送信者によって送られたシグナルに接続する<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>シグナルの中には何度も送信されるものがありますが、そのようなシグナルの特定のサブセットだけを受信したいと思うかも知れません。例えば、モデルが保存される前に送られるシグナル <a class=\"reference internal\" href=\"/ja/5.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\">django.db.models.signals.pre_save</code></a> を考えてみましょう。ほとんどの場合、 <em>どの</em> モデルが保存されるかを知る必要はありません。ある <em>特定の</em> モデルが保存されたときだけ知る必要があります。</p>\n<p>このような場合、特定の送信者のみが送信するシグナルを受信するように登録できます。 <a class=\"reference internal\" href=\"/ja/5.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\">django.db.models.signals.pre_save</code></a> の場合、送信者は保存されるモデルクラスになるので、あるモデルから送信されるシグナルだけが欲しいことを示すことができます:</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=\"nn\">django.db.models.signals</span> <span class=\"kn\">import</span> pre_save\n<span class=\"kn\">from</span> <span class=\"nn\">django.dispatch</span> <span class=\"kn\">import</span> receiver\n<span class=\"kn\">from</span> <span class=\"nn\">myapp.models</span> <span class=\"kn\">import</span> MyModel\n\n\n<span class=\"nd\">@receiver</span><span class=\"p\">(</span>pre_save<span class=\"p\">,</span> sender<span class=\"o\">=</span>MyModel<span class=\"p\">)</span>\n<span class=\"k\">def</span> <span class=\"nf\">my_handler</span><span class=\"p\">(</span>sender<span class=\"p\">,</span> <span class=\"o\">**</span>kwargs<span class=\"p\">):</span> <span class=\"o\">...</span>\n</code></pre></div>\n<p><code class=\"docutils literal notranslate\">my_handler</code> 関数は <code class=\"docutils literal notranslate\">MyModel</code> のインスタンスが保存されたときにだけ呼び出されます。</p>\n<p>異なるシグナルは異なるオブジェクトを送信元として使用します。それぞれのシグナルの詳細については <a class=\"reference internal\" href=\"/ja/5.1/ref/signals/\"><span class=\"doc\">組み込みシグナルのドキュメント</span></a> を参照する必要があります。</p>\n</section>\n<section id=\"preventing-duplicate-signals\">\n<span id=\"id3\"></span><h3>重複したシグナルを防止する<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>状況によっては、レシーバーをシグナルに接続するコードが複数回実行されることがあります。そのため、レシーバ関数が複数回登録され、シグナルイベントに対して複数回呼び出される可能性があります。例えば、 <a class=\"reference internal\" href=\"/ja/5.1/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</code></a> メソッドがテスト中に複数回実行されるかもしれません。より一般的には、シグナル登録はインポートされた回数だけ実行されるため、 シグナルを定義したモジュールをインポートしたプロジェクトではどこでも発生します。</p>\n<p>この動作が問題となる場合 (シグナルを使用してモデルが保存されるたびにメールを送信する場合など)、受信関数を識別するために <code class=\"docutils literal notranslate\">dispatch_uid</code> 引数に一意な識別子を渡します。この識別子は通常文字列ですが、ハッシュ可能なオブジェクトであれば何でもかまいません。この結果、受信関数は一意な <code class=\"docutils literal notranslate\">dispatch_uid</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=\"nn\">django.core.signals</span> <span class=\"kn\">import</span> request_finished\n\nrequest_finished<span class=\"o\">.</span>connect<span class=\"p\">(</span>my_callback<span class=\"p\">,</span> dispatch_uid<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>シグナルの定義と送信<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>アプリケーションは信号インフラを利用し、独自の信号を提供できます。</p>\n<aside class=\"admonition-when-to-use-custom-signals admonition\" role=\"note\">\n<p class=\"admonition-title\">カスタムシグナルを使うべきタイミング</p>\n<p>シグナルは暗黙の関数呼び出しなので、デバッグが難しくなります。カスタムシグナルの送信側と受信側の両方がプロジェクト内にある場合は、明示的な関数呼び出しを使ったほうがよいでしょう。</p>\n</aside>\n<section id=\"defining-signals\">\n<h3>シグナルを定義する<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\">class</span> </em><span class=\"sig-name descname\">Signal</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>すべてのシグナルは <a class=\"reference internal\" href=\"#django.dispatch.Signal\" title=\"django.dispatch.Signal\"><code class=\"xref py py-class docutils literal notranslate\">django.dispatch.Signal</code></a> インスタンスです。</p>\n<p>例:</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=\"nn\">django.dispatch</span>\n\npizza_done <span class=\"o\">=</span> django<span class=\"o\">.</span>dispatch<span class=\"o\">.</span>Signal<span class=\"p\">()</span>\n</code></pre></div>\n<p>このコードは、<code class=\"docutils literal notranslate\">pizza_done</code> シグナルを宣言しています。</p>\n</section>\n<section id=\"sending-signals\">\n<span id=\"id5\"></span><h3>シグナルを送信する<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>Django でシグナルを同期的に送信する方法は2つあります。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.send\">\n<span class=\"sig-prename descclassname\">Signal.</span><span class=\"sig-name descname\">send</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sender</em>, <em class=\"sig-param\"><span class=\"o\">**</span>kwargs</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\">Signal.</span><span class=\"sig-name descname\">send_robust</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sender</em>, <em class=\"sig-param\"><span class=\"o\">**</span>kwargs</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>シグナルは非同期に送信することもできます。</p>\n<dl class=\"py method\">\n<dt class=\"sig sig-object py\" id=\"django.dispatch.Signal.asend\">\n<span class=\"sig-prename descclassname\">Signal.</span><span class=\"sig-name descname\">asend</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sender</em>, <em class=\"sig-param\"><span class=\"o\">**</span>kwargs</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\">Signal.</span><span class=\"sig-name descname\">asend_robust</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">sender</em>, <em class=\"sig-param\"><span class=\"o\">**</span>kwargs</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>シグナルを送信するには、<a class=\"reference internal\" href=\"#django.dispatch.Signal.send\" title=\"django.dispatch.Signal.send\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.send()</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\">Signal.send_robust()</code></a>、<a class=\"reference internal\" href=\"#django.dispatch.Signal.asend\" title=\"django.dispatch.Signal.asend\"><code class=\"xref py py-meth docutils literal notranslate\">await Signal.asend()</code></a>、<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\">await Signal.asend_robust()</code></a> のどれかを呼び出します。引数として <code class=\"docutils literal notranslate\">sender</code> (ほとんどの場合クラス) を指定する必要があり、他のキーワード引数を好きなだけ指定できます。</p>\n<p>たとえば、<code class=\"docutils literal notranslate\">pizza_done</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=\"nc\">PizzaStore</span><span class=\"p\">:</span>\n    <span class=\"o\">...</span>\n\n    <span class=\"k\">def</span> <span class=\"nf\">send_pizza</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> toppings<span class=\"p\">,</span> size<span class=\"p\">):</span>\n        pizza_done<span class=\"o\">.</span>send<span class=\"p\">(</span>sender<span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">,</span> toppings<span class=\"o\">=</span>toppings<span class=\"p\">,</span> size<span class=\"o\">=</span>size<span class=\"p\">)</span>\n        <span class=\"o\">...</span>\n</code></pre></div>\n<p>4つのメソッドはすべて、呼び出されたレシーバー関数とそのレスポンス値のリストを表すタプルのペア <code class=\"docutils literal notranslate\">[(receiver, response), ...]</code> のリストを返します。</p>\n<p><code class=\"docutils literal notranslate\">send()</code> は <code class=\"docutils literal notranslate\">send_robust()</code> と異なり、レシーバ関数が発生させた例外をどのようにハンド リングするかという点で異なります。 <code class=\"docutils literal notranslate\">send()</code> はレシーバが発生させた例外をキャッチしません。そのため、エラーが発生してもすべてのレシーバにシグナルが通知されるとは限りません。</p>\n<p><code class=\"docutils literal notranslate\">send_robust()</code> は Python の <code class=\"docutils literal notranslate\">Exception</code> クラスに由来するすべてのエラーをキャッチし、すべてのレシーバにシグナルが通知されるようにします。エラーが発生した場合、エラーを発生させたレシーバのタプルのペアにエラーインスタンスが返されます。</p>\n<p>トレースバックは <code class=\"docutils literal notranslate\">send_robust()</code> を呼び出したときに返されるエラーの <code class=\"docutils literal notranslate\">__traceback__</code> 属性に存在します。</p>\n<p><code class=\"docutils literal notranslate\">asend()</code> は <code class=\"docutils literal notranslate\">send()</code> と似ていますが、await しなければならないコルーチンです:</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=\"nf\">asend_pizza</span><span class=\"p\">(</span><span class=\"bp\">self</span><span class=\"p\">,</span> toppings<span class=\"p\">,</span> size<span class=\"p\">):</span>\n    <span class=\"k\">await</span> pizza_done<span class=\"o\">.</span>asend<span class=\"p\">(</span>sender<span class=\"o\">=</span><span class=\"bp\">self</span><span class=\"o\">.</span><span class=\"vm\">__class__</span><span class=\"p\">,</span> toppings<span class=\"o\">=</span>toppings<span class=\"p\">,</span> size<span class=\"o\">=</span>size<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\">send()</code> or <code class=\"docutils literal notranslate\">asend()</code> is used. Synchronous receivers will be\ncalled using <a class=\"reference internal\" href=\"/ja/5.1/topics/async/#asgiref.sync.sync_to_async\" title=\"asgiref.sync.sync_to_async\"><code class=\"xref py py-func docutils literal notranslate\">sync_to_async()</code></a> when invoked via <code class=\"docutils literal notranslate\">asend()</code>. Asynchronous\nreceivers will be called using <a class=\"reference internal\" href=\"/ja/5.1/topics/async/#asgiref.sync.async_to_sync\" title=\"asgiref.sync.async_to_sync\"><code class=\"xref py py-func docutils literal notranslate\">async_to_sync()</code></a> when invoked via\n<code class=\"docutils literal notranslate\">send()</code>. Similar to the <a class=\"reference internal\" href=\"/ja/5.1/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\">send()</code> or <code class=\"docutils literal notranslate\">asend()</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\">asyncio.gather()</code>.</p>\n<p>非同期のリクエスト/レスポンス・サイクル以外のすべての組み込みシグナルは <a class=\"reference internal\" href=\"#django.dispatch.Signal.send\" title=\"django.dispatch.Signal.send\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.send()</code></a> を使ってディスパッチされます。</p>\n<aside class=\"version-note version-changed\" data-version=\"5.0\" role=\"note\">\n<p class=\"version-note-title\">Changed in Django 5.0</p><p>非同期シグナルのサポートが追加されました。</p>\n</aside>\n</section>\n</section>\n<section id=\"disconnecting-signals\">\n<h2>シグナルを切断する<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\">Signal.</span><span class=\"sig-name descname\">disconnect</span><span class=\"sig-paren\">(</span><em class=\"sig-param\">receiver<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">sender<span class=\"o\">=</span><span class=\"default_value\">None</span></em>, <em class=\"sig-param\">dispatch_uid<span class=\"o\">=</span><span class=\"default_value\">None</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>シグナルからレシーバーを切断するには <a class=\"reference internal\" href=\"#django.dispatch.Signal.disconnect\" title=\"django.dispatch.Signal.disconnect\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.disconnect()</code></a> を呼び出します。引数は <a class=\"reference internal\" href=\"#django.dispatch.Signal.connect\" title=\"django.dispatch.Signal.connect\"><code class=\"xref py py-meth docutils literal notranslate\">Signal.connect()</code></a> の説明と同じです。このメソッドは、レシーバが切断された場合は <code class=\"docutils literal notranslate\">True</code> を、切断されなかった場合は <code class=\"docutils literal notranslate\">False</code> を返します。<code class=\"docutils literal notranslate\">sender</code> が <code class=\"docutils literal notranslate\">&lt;app label&gt;.&lt;model&gt;</code> への遅延参照として渡された場合、このメソッドは常に <code class=\"docutils literal notranslate\">None</code> を返します。</p>\n<p>引数 <code class=\"docutils literal notranslate\">receiver</code> は、切断する登録済みのレシーバを指定します。レシーバを識別するために <code class=\"docutils literal notranslate\">dispatch_uid</code> を使用する場合は <code class=\"docutils literal notranslate\">None</code> を指定します。</p>\n</section>","rootId":"module-django.dispatch","toc":[{"title":"シグナルを待ち受ける","anchor":"listening-to-signals","children":[{"title":"レシーバ関数","anchor":"receiver-functions","children":[]},{"title":"レシーバ関数に接続する","anchor":"connecting-receiver-functions","children":[]},{"title":"特定の送信者によって送られたシグナルに接続する","anchor":"connecting-to-signals-sent-by-specific-senders","children":[]},{"title":"重複したシグナルを防止する","anchor":"preventing-duplicate-signals","children":[]}]},{"title":"シグナルの定義と送信","anchor":"defining-and-sending-signals","children":[{"title":"シグナルを定義する","anchor":"defining-signals","children":[]},{"title":"シグナルを送信する","anchor":"sending-signals","children":[]}]},{"title":"シグナルを切断する","anchor":"disconnecting-signals","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Django を使う","url":"/ja/5.1/topics/"}],"prev":{"docname":"topics/settings","title":"Djangoの設定","url":"/ja/5.1/topics/settings/"},"next":{"docname":"topics/checks","title":"システムチェックフレームワーク","url":"/ja/5.1/topics/checks/"},"formats":{"html":"/ja/5.1/topics/signals/","markdown":"/ja/5.1/topics/signals.md","json":"/ja/5.1/topics/signals.json"},"source":"https://github.com/django/django/blob/stable/5.1.x/docs/topics/signals.txt","official":"https://docs.djangoproject.com/ja/5.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","it","pt-br","ko","es","el","pl"]}