<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # 信號 Django包含一個“信號的分發器”,允許解耦的應用在信號出現在框架的任何地方時,都能獲得通知。簡單來說,信號允許指定的&nbsp;_發送器_通知一系列的_接收器_,一些操作已經發生了。當一些代碼會相同事件感興趣時,會十分有幫助。 Django 提供了[_一系列的內建信號_](../ref/signals.html),允許用戶的代碼獲得DJango的特定操作的通知。這包含一些有用的通知: * [`django.db.models.signals.pre_save`](../ref/signals.html#django.db.models.signals.pre_save "django.db.models.signals.pre_save") & [`django.db.models.signals.post_save`](../ref/signals.html#django.db.models.signals.post_save "django.db.models.signals.post_save") 在模型&nbsp;[`save()`](../ref/models/instances.html#django.db.models.Model.save "django.db.models.Model.save")方法調用之前或之后發送。 * [`django.db.models.signals.pre_delete`](../ref/signals.html#django.db.models.signals.pre_delete "django.db.models.signals.pre_delete") & [`django.db.models.signals.post_delete`](../ref/signals.html#django.db.models.signals.post_delete "django.db.models.signals.post_delete") 在模型[`delete()`](../ref/models/instances.html#django.db.models.Model.delete "django.db.models.Model.delete")方法或查詢集的[`delete()`](../ref/models/querysets.html#django.db.models.query.QuerySet.delete "django.db.models.query.QuerySet.delete") 方法調用之前或之后發送。 * [`django.db.models.signals.m2m_changed`](../ref/signals.html#django.db.models.signals.m2m_changed "django.db.models.signals.m2m_changed") 模型上的 [`ManyToManyField`](../ref/models/fields.html#django.db.models.ManyToManyField "django.db.models.ManyToManyField") 修改時發送。 * [`django.core.signals.request_started`](../ref/signals.html#django.core.signals.request_started "django.core.signals.request_started") & [`django.core.signals.request_finished`](../ref/signals.html#django.core.signals.request_finished "django.core.signals.request_finished") Django建立或關閉HTTP 請求時發送。 關于完整列表以及每個信號的完整解釋,請見[_內建信號的文檔_](../ref/signals.html) 。 你也可以[定義和發送你自己的自定義信號](#defining-and-sending-signals);見下文。 ## 監聽信號 你需要注冊一個_接收器_函數來接受信號,它在信號使用[`Signal.connect()`](#django.dispatch.Signal.connect "django.dispatch.Signal.connect")發送時被調用: `Signal.``connect`(_receiver_[, _sender=None_, _weak=True_, _dispatch_uid=None_]) <table class="docutils field-list" frame="void" rules="none"><colgroup><col class="field-name"><col class="field-body"></colgroup><tbody valign="top"><tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body">* **receiver** – 和這個信號連接的回調函數。詳見[_接收器函數_](#receiver-functions)。 * **sender** – 指定一個特定的發送器,來從它那里接受信號。詳見[_連接由指定發送器發送的信號_](#connecting-to-specific-signals)。 * **weak** – DJango通常以弱引用儲存信號處理器。這就是說,如果你的接收器是個局部變量,可能會被垃圾回收。當你調用信號的`connect()`方法是,傳遞&nbsp;`weak=False`來防止這樣做。 * **dispatch_uid** – 一個信號接收器的唯一標識符,以防信號多次發送。詳見[_防止重復的信號_](#preventing-duplicate-signals)。 </td></tr></tbody></table> 讓我們來看一看它如何通過注冊在每次在HTTP請求結束時調用的信號來工作。我們將會連接到[`request_finished`](../ref/signals.html#django.core.signals.request_finished "django.core.signals.request_finished") 信號。 ### 接收器函數 首先,我們需要定義接收器函數。接受器可以是Python函數或者方法: ``` def my_callback(sender, **kwargs): print("Request finished!") ``` 注意函數接受`sender`函數,以及通配符關鍵字參數(`**kwargs`);所有信號處理器都必須接受這些參數。 我們[過一會兒](#connecting-to-signals-sent-by-specific-senders)再關注發送器,現在先看一看`**kwargs`參數。所有信號都發送關鍵字參數,并且可以在任何時候修改這些關鍵字參數。在&nbsp;[`request_finished`](../ref/signals.html#django.core.signals.request_finished "django.core.signals.request_finished")的情況下,它被記錄為不發送任何參數,這意味著我們可能需要像`my_callback(sender)`一樣編寫我們自己的信號處理器。 這是錯誤的 -- 實際上,如果你這么做了,Django會拋出異常。這是因為無論什么時候信號中添加了參數,你的接收器都必須能夠處理這些新的參數。 ### 連接接收器函數 有兩種方法可以將一個接收器連接到信號。你可以采用手動連接的方法: ``` from django.core.signals import request_finished request_finished.connect(my_callback) ``` 或者使用[`receiver()`](#django.dispatch.receiver "django.dispatch.receiver") 裝飾器來自動連接: `receiver`(_signal_) <table class="docutils field-list" frame="void" rules="none"><colgroup><col class="field-name"><col class="field-body"></colgroup><tbody valign="top"><tr class="field-odd field"><th class="field-name">Parameters:</th><td class="field-body">**signal** – A signal or a list of signals to connect a function to.</td></tr></tbody></table> 下面是使用裝飾器連接的方法: ``` from django.core.signals import request_finished from django.dispatch import receiver @receiver(request_finished) def my_callback(sender, **kwargs): print("Request finished!") ``` 現在,我們的`my_callback`函數會在每次請求結束時調用。 這段代碼應該放在哪里? 嚴格來說,信號處理和注冊的代碼應該放在你想要的任何地方,但是推薦避免放在應用的根模塊和`models`模塊中,以盡量減少產生導入代碼的副作用。 實際上,信號處理通常定義在應用相關的`signals`子模塊中。信號接收器在你應用配置類中的[`ready()`](../ref/applications.html#django.apps.AppConfig.ready "django.apps.AppConfig.ready") 方法中連接。如果你使用;額&nbsp;[`receiver()`](#django.dispatch.receiver "django.dispatch.receiver")裝飾器,只是在[`ready()`](../ref/applications.html#django.apps.AppConfig.ready "django.apps.AppConfig.ready")內部導入`signals`子模塊就可以了。 Changed in Django 1.7: 由于[`ready()`](../ref/applications.html#django.apps.AppConfig.ready "django.apps.AppConfig.ready")并不在Django之前版本中存在,信號的注冊通常在`models`模塊中進行。 注意 [`ready()`](../ref/applications.html#django.apps.AppConfig.ready "django.apps.AppConfig.ready") 方法會在測試期間執行多次,所以你可能想要[_防止重復的信號_](#preventing-duplicate-signals),尤其是打算在測試中發送它們的情況。 ### 連接由指定發送器發送的信號 一些信號會發送多次,但是你只想接收這些信號的一個確定的子集。例如,考慮 [`django.db.models.signals.pre_save`](../ref/signals.html#django.db.models.signals.pre_save "django.db.models.signals.pre_save") 信號,它在模型保存之前發送。大多數情況下,你并不需要知道&nbsp;_任何_模型何時保存 -- 只需要知道一個_特定的_模型何時保存。 在這些情況下,你可以通過注冊來接收只由特定發送器發出的信號。對于[`django.db.models.signals.pre_save`](../ref/signals.html#django.db.models.signals.pre_save "django.db.models.signals.pre_save")的情況, 發送者是被保存的模型類,所以你可以認為你只需要由某些模型發出的信號: ``` from django.db.models.signals import pre_save from django.dispatch import receiver from myapp.models import MyModel @receiver(pre_save, sender=MyModel) def my_handler(sender, **kwargs): ... ``` `my_handler`函數只在`MyModel`實例保存時被調用。 不同的信號使用不同的對象作為他們的發送器;對于每個特定信號的細節,你需要查看[_內建信號的文檔_](../ref/signals.html)。 ### 防止重復的信號 在一些情況下,向接收者發送信號的代碼可能會執行多次。這會使你的接收器函數被注冊多次,并且導致它對于同一信號事件被調用多次。 如果這樣的行為會導致問題(例如在任何時候模型保存時使用信號來發送郵件),傳遞一個唯一的標識符作為&nbsp;`dispatch_uid`參數來標識你的接收器函數。標識符通常是一個字符串,雖然任何可計算哈希的對象都可以。最后的結果是,對于每個唯一的`dispatch_uid`值,你的接收器函數都只被信號調用一次: ``` from django.core.signals import request_finished request_finished.connect(my_callback, dispatch_uid="my_unique_identifier") ``` ## 定義和發送信號 你的應用可以利用信號功能來提供自己的信號。 ### 定義信號 _class _`Signal`([_providing_args=list_]) 所有信號都是&nbsp;[`django.dispatch.Signal`](#django.dispatch.Signal "django.dispatch.Signal") 的實例。`providing_args`是一個列表,包含參數的名字,它們由信號提供給監聽者。理論上是這樣,但是實際上并沒有任何檢查來保證向監聽者提供了這些參數。 例如: ``` import django.dispatch pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"]) ``` 這段代碼聲明了`pizza_done`信號,它向接受者提供`toppings`和&nbsp;`size` 參數。 要記住你可以在任何時候修改參數的列表,所以首次嘗試的時候不需要完全確定API。 ### 發送信號 Django中有兩種方法用于發送信號。 `Signal.``send`(_sender_, _**kwargs_) `Signal.``send_robust`(_sender_, _**kwargs_) 調用&nbsp;[`Signal.send()`](#django.dispatch.Signal.send "django.dispatch.Signal.send")或者[`Signal.send_robust()`](#django.dispatch.Signal.send_robust "django.dispatch.Signal.send_robust")來發送信號。你必須提供`sender` 參數(大多數情況下它是一個類),并且可以提供盡可能多的關鍵字參數。 例如,這樣來發送我們的`pizza_done`信號: ``` class PizzaStore(object): ... def send_pizza(self, toppings, size): pizza_done.send(sender=self.__class__, toppings=toppings, size=size) ... ``` `send()` 和`send_robust()`都會返回一個含有二元組的列表 `[(receiver, response), ... `],它代表了被調用的接收器函數和他們的響應值。 `send()` 與 `send_robust()`在處理接收器函數產生的異常時有所不同。`send()`_不會_ 捕獲任何由接收器產生的異常。它會簡單地讓錯誤往上傳遞。所以在錯誤產生的情況,不是所有接收器都會獲得通知。 `send_robust()`捕獲所有繼承自Python `Exception`類的異常,并且確保所有接收器都能得到信號的通知。如果發生了錯誤,錯誤的實例會在產生錯誤的接收器的二元組中返回。 New in Django 1.8: 調用`send_robust()`的時候,所返回的錯誤的`__traceback__`屬性上會帶有&nbsp;traceback。 ## 斷開信號 `Signal.``disconnect`([_receiver=None_, _sender=None_, _weak=True_, _dispatch_uid=None_]) 調用[`Signal.disconnect()`](#django.dispatch.Signal.disconnect "django.dispatch.Signal.disconnect")來斷開信號的接收器。&nbsp;[`Signal.connect()`](#django.dispatch.Signal.connect "django.dispatch.Signal.connect")中描述了所有參數。如果接收器成功斷開,返回&nbsp;`True` ,否則返回`False`。 `receiver`參數表示要斷開的已注冊接收器。如果`dispatch_uid` 用于定義接收器,可以為`None`。 Changed in Django 1.8: 增加了返回的布爾值。 > 譯者:[Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html),原文:[Signals](https://docs.djangoproject.com/en/1.8/topics/signals/)。 > > 本文以 [CC BY-NC-SA 3.0](http://creativecommons.org/licenses/by-nc-sa/3.0/cn/) 協議發布,轉載請保留作者署名和文章出處。 > > [Django 文檔協作翻譯小組](http://python.usyiyi.cn/django/index.html)人手緊缺,有興趣的朋友可以加入我們,完全公益性質。交流群:467338606。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看