{"title":"Sinyal","version":"6.0","locale":"id","docname":"topics/signals","url":"/id/6.0/topics/signals/","canonical":"https://djangodocs.dev/id/6.0/topics/signals/","summary":"Django includes a \"signal dispatcher\" which helps decoupled applications get notified when actions occur elsewhere in the framework.","html":"<span id=\"signals\"></span><h1>Sinyal<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 &quot;signal dispatcher&quot; 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=\"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's <a class=\"reference internal\" href=\"/id/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\">Menentukan dan mengirim sinyal</span></a> below.</p>\n<aside class=\"admonition admonition-warning\" role=\"note\">\n<p class=\"admonition-title\">Peringatan</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>Mendengarkan ke sinyal<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\">Signal.connect()</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\">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\">Parameter<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\">Fungsi penerima</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\">weak=False</code> when you call\nthe signal's <code class=\"docutils literal notranslate\">connect()</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\">Mencegah sinyal rangkap</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=\"/id/6.0/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> signal.</p>\n<section id=\"receiver-functions\">\n<span id=\"id1\"></span><h3>Fungsi penerima<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>Pertama, kami butuh menentukan fungsi penerima. Penerima dapat menjadi fungsi Phyton apapun atau cara:</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>Notice that the function takes a <code class=\"docutils literal notranslate\">sender</code> argument, along with wildcard\nkeyword arguments (<code class=\"docutils literal notranslate\">**kwargs</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\">**kwargs</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=\"/id/6.0/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>, 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\">my_callback(sender)</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\">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>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>Menyambung fungsi penerima<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=\"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>Cara lain, anda dapat menggunakan penghias  <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\">Parameter<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=\"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>Now, our <code class=\"docutils literal notranslate\">my_callback</code> function will be called each time a request finishes.</p>\n<aside class=\"admonition-where-should-this-code-live admonition\" role=\"note\">\n<p class=\"admonition-title\">Dimana seharusnya kode ini tinggal?</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\">models</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\">signals</code>\nsubmodule of the application they relate to. Signal receivers are\nconnected in the <a class=\"reference internal\" href=\"/id/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</code></a> method of your\napplication <a class=\"reference internal\" href=\"/id/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\">receiver()</code></a> decorator, import the <code class=\"docutils literal notranslate\">signals</code>\nsubmodule inside <a class=\"reference internal\" href=\"/id/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</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=\"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\">Catatan</p>\n<p>The <a class=\"reference internal\" href=\"/id/6.0/ref/applications/#django.apps.AppConfig.ready\" title=\"django.apps.AppConfig.ready\"><code class=\"xref py py-meth docutils literal notranslate\">ready()</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=\"/id/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\">django.db.models.signals.pre_save</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=\"/id/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\">django.db.models.signals.pre_save</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=\"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>The <code class=\"docutils literal notranslate\">my_handler</code> function will only be called when an instance of <code class=\"docutils literal notranslate\">MyModel</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=\"/id/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>Mencegah sinyal rangkap<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\">dispatch_uid</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=\"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\n\nmy_signal<span class=\"o\">.</span>connect<span class=\"p\">(</span>my_handler<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\">self</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=\"nf\">connect_signals</span><span class=\"p\">():</span>\n    backend <span class=\"o\">=</span> Backend<span class=\"p\">()</span>\n    my_signal<span class=\"o\">.</span>connect<span class=\"p\">(</span>backend<span class=\"o\">.</span>my_handler<span class=\"p\">)</span>  <span class=\"c1\"># A distinct receiver.</span>\n\n\nconnect_signals<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\">dispatch_uid</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\">dispatch_uid</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=\"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>Menentukan dan mengirim sinyal<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>Aplikasi anda dapat mengambil keuntungan dari infrastruktur sinyal dan menyediakan sinyal sendiri.</p>\n<aside class=\"admonition-when-to-use-custom-signals admonition\" role=\"note\">\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>Menentukan sinyal<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>All signals are <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> instances.</p>\n<p>Sebagai contoh:</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>This declares a <code class=\"docutils literal notranslate\">pizza_done</code> signal.</p>\n</section>\n<section id=\"sending-signals\">\n<span id=\"id5\"></span><h3>Mengirim sinyal<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\">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>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\">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>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\">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>,\n<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>, 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\">await Signal.asend_robust()</code></a>. You must provide the\n<code class=\"docutils literal notranslate\">sender</code> argument (which is a class most of the time) and may provide as many\nother keyword arguments as you like.</p>\n<p>Sebagai contoh, ini adalah bagaimana mengirim sinyal <code class=\"docutils literal notranslate\">pizza_done</code> kami mungkin terlihat:</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>All four methods return a list of tuple pairs <code class=\"docutils literal notranslate\">[(receiver, response), ...]</code>,\nrepresenting the list of called receiver functions and their response values.</p>\n<p><code class=\"docutils literal notranslate\">send()</code> differs from <code class=\"docutils literal notranslate\">send_robust()</code> in how exceptions raised by receiver\nfunctions are handled. <code class=\"docutils literal notranslate\">send()</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\">send_robust()</code> catches all errors derived from Python's <code class=\"docutils literal notranslate\">Exception</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\">__traceback__</code> attribute of the errors\nreturned when calling <code class=\"docutils literal notranslate\">send_robust()</code>.</p>\n<p><code class=\"docutils literal notranslate\">asend()</code> is similar to <code class=\"docutils literal notranslate\">send()</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=\"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=\"/id/6.0/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=\"/id/6.0/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=\"/id/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\">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>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\">Signal.send()</code></a>.</p>\n</section>\n</section>\n<section id=\"disconnecting-signals\">\n<h2>Memutus sambungan sinyal<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>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\">Signal.disconnect()</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\">Signal.connect()</code></a>. The method returns\n<code class=\"docutils literal notranslate\">True</code> if a receiver was disconnected and <code class=\"docutils literal notranslate\">False</code> if not. When <code class=\"docutils literal notranslate\">sender</code>\nis passed as a lazy reference to <code class=\"docutils literal notranslate\">&lt;app label&gt;.&lt;model&gt;</code>, this method always\nreturns <code class=\"docutils literal notranslate\">None</code>.</p>\n<p>Argumen <code class=\"docutils literal notranslate\">receiver</code> menunjukkan penerima terdaftar untuk tidak terhubung. Itu mungkin <code class=\"docutils literal notranslate\">None</code> jika <code class=\"docutils literal notranslate\">dispatch_uid</code> digunakan untuk mencirikan penerima.</p>\n</section>","rootId":"module-django.dispatch","toc":[{"title":"Mendengarkan ke sinyal","anchor":"listening-to-signals","children":[{"title":"Fungsi penerima","anchor":"receiver-functions","children":[]},{"title":"Menyambung fungsi penerima","anchor":"connecting-receiver-functions","children":[]},{"title":"Connecting to signals sent by specific senders","anchor":"connecting-to-signals-sent-by-specific-senders","children":[]},{"title":"Mencegah sinyal rangkap","anchor":"preventing-duplicate-signals","children":[]}]},{"title":"Menentukan dan mengirim sinyal","anchor":"defining-and-sending-signals","children":[{"title":"Menentukan sinyal","anchor":"defining-signals","children":[]},{"title":"Mengirim sinyal","anchor":"sending-signals","children":[]}]},{"title":"Memutus sambungan sinyal","anchor":"disconnecting-signals","children":[]}],"breadcrumbs":[{"docname":"topics/index","title":"Menggunakan Django","url":"/id/6.0/topics/"}],"prev":{"docname":"topics/settings","title":"Pengaturan Django","url":"/id/6.0/topics/settings/"},"next":{"docname":"topics/checks","title":"Kerangka sistem pemeriksaan","url":"/id/6.0/topics/checks/"},"formats":{"html":"/id/6.0/topics/signals/","markdown":"/id/6.0/topics/signals.md","json":"/id/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/id/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"]}