在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Python/ 信號
點擊劫持保護(hù)
安全問題歸檔
Model 類參考
將遺留數(shù)據(jù)庫整合到Django
關(guān)聯(lián)對象參考
內(nèi)建基于類的視圖的API
聚合
Django 中的用戶認(rèn)證
django.contrib.humanize
Django管理文檔生成器
分頁
使用Django輸出CSV
加密簽名
文件儲存API
安全
Django中的測試
國際化和本地化
為Django編寫首個補(bǔ)丁
條件表達(dá)式
日志
模型元選項
部署靜態(tài)文件
執(zhí)行查詢
使用Django認(rèn)證系統(tǒng)
基于類的視圖
中間件
編寫自定義的django-admin命令
Django 的設(shè)置
格式本地化
數(shù)據(jù)庫訪問優(yōu)化
錯誤報告
基于類的內(nèi)建通用視圖
編寫自定義存儲系統(tǒng)
編寫你的第一個 Django 程序 第3部分
編寫數(shù)據(jù)庫遷移
使用表單
編寫你的第一個 Django 程序 第2部分
編寫你的第一個 Django 程序 第1部分
如何使用會話
系統(tǒng)檢查框架
新手入門
信號
編寫視圖
如何使用WSGI 部署
編寫你的第一個Django應(yīng)用,第6部分
常見的網(wǎng)站應(yīng)用工具
Widgets
內(nèi)建的視圖
模型實例參考
視圖層
Django中的密碼管理
高級教程:如何編寫可重用的應(yīng)用
國際化和本地化
"本地特色"附加功能
TemplateResponse 和 SimpleTemplateResponse
模式編輯器
文件上傳
快速安裝指南
部署 Django
表單 API
表單素材 ( <code>Media</code> 類)
管理文件
其它核心功能
查找 API 參考
表單
Admin
數(shù)據(jù)庫函數(shù)
自定義查找
使用基于類的視圖處理表單
管理操作
開發(fā)過程
編寫你的第一個Django應(yīng)用,第5部分
進(jìn)行原始的sql查詢
模型層
多數(shù)據(jù)庫
編寫你的第一個 Django 程序 第4部分
Django安全
Django 初探
Django異常
重定向應(yīng)用
按需內(nèi)容處理
管理器
視圖裝飾器
驗證器
使用Django輸出PDF
File對象
Django 的快捷函數(shù)
基于類的通用視圖 —— 索引
為模型提供初始數(shù)據(jù)
模板層
URL調(diào)度器
中間件
模型

信號

Django包含一個“信號的分發(fā)器”,允許解耦的應(yīng)用在信號出現(xiàn)在框架的任何地方時,都能獲得通知。簡單來說,信號允許指定的 _發(fā)送器_通知一系列的接收器,一些操作已經(jīng)發(fā)生了。當(dāng)一些代碼會相同事件感興趣時,會十分有幫助。

Django 提供了一系列的內(nèi)建信號,允許用戶的代碼獲得DJango的特定操作的通知。這包含一些有用的通知:

關(guān)于完整列表以及每個信號的完整解釋,請見內(nèi)建信號的文檔 。

你也可以定義和發(fā)送你自己的自定義信號;見下文。

監(jiān)聽信號

你需要注冊一個_接收器_函數(shù)來接受信號,它在信號使用Signal.connect()發(fā)送時被調(diào)用:

Signal.``connect(receiver[, sender=None, weak=True, _dispatchuid=None])

Parameters: * **receiver** – 和這個信號連接的回調(diào)函數(shù)。詳見[_接收器函數(shù)_](#receiver-functions)。 * **sender** – 指定一個特定的發(fā)送器,來從它那里接受信號。詳見[_連接由指定發(fā)送器發(fā)送的信號_](#connecting-to-specific-signals)。 * **weak** – DJango通常以弱引用儲存信號處理器。這就是說,如果你的接收器是個局部變量,可能會被垃圾回收。當(dāng)你調(diào)用信號的`connect()`方法是,傳遞?`weak=False`來防止這樣做。 * **dispatch_uid** – 一個信號接收器的唯一標(biāo)識符,以防信號多次發(fā)送。詳見[_防止重復(fù)的信號_](#preventing-duplicate-signals)。

讓我們來看一看它如何通過注冊在每次在HTTP請求結(jié)束時調(diào)用的信號來工作。我們將會連接到request_finished 信號。

接收器函數(shù)

首先,我們需要定義接收器函數(shù)。接受器可以是Python函數(shù)或者方法:

def my_callback(sender, **kwargs):
    print("Request finished!")

注意函數(shù)接受sender函數(shù),以及通配符關(guān)鍵字參數(shù)(**kwargs);所有信號處理器都必須接受這些參數(shù)。

我們過一會兒再關(guān)注發(fā)送器,現(xiàn)在先看一看**kwargs參數(shù)。所有信號都發(fā)送關(guān)鍵字參數(shù),并且可以在任何時候修改這些關(guān)鍵字參數(shù)。在 request_finished的情況下,它被記錄為不發(fā)送任何參數(shù),這意味著我們可能需要像my_callback(sender)一樣編寫我們自己的信號處理器。

這是錯誤的 -- 實際上,如果你這么做了,Django會拋出異常。這是因為無論什么時候信號中添加了參數(shù),你的接收器都必須能夠處理這些新的參數(shù)。

連接接收器函數(shù)

有兩種方法可以將一個接收器連接到信號。你可以采用手動連接的方法:

from django.core.signals import request_finished

request_finished.connect(my_callback)

或者使用receiver() 裝飾器來自動連接:

receiver(signal)

Parameters: **signal** – A signal or a list of signals to connect a function to.

下面是使用裝飾器連接的方法:

from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
    print("Request finished!")

現(xiàn)在,我們的my_callback函數(shù)會在每次請求結(jié)束時調(diào)用。

這段代碼應(yīng)該放在哪里?

嚴(yán)格來說,信號處理和注冊的代碼應(yīng)該放在你想要的任何地方,但是推薦避免放在應(yīng)用的根模塊和models模塊中,以盡量減少產(chǎn)生導(dǎo)入代碼的副作用。

實際上,信號處理通常定義在應(yīng)用相關(guān)的signals子模塊中。信號接收器在你應(yīng)用配置類中的ready() 方法中連接。如果你使用;額 receiver()裝飾器,只是在ready()內(nèi)部導(dǎo)入signals子模塊就可以了。

Changed in Django 1.7:

由于ready()并不在Django之前版本中存在,信號的注冊通常在models模塊中進(jìn)行。

注意

ready() 方法會在測試期間執(zhí)行多次,所以你可能想要防止重復(fù)的信號,尤其是打算在測試中發(fā)送它們的情況。

連接由指定發(fā)送器發(fā)送的信號

一些信號會發(fā)送多次,但是你只想接收這些信號的一個確定的子集。例如,考慮 django.db.models.signals.pre_save 信號,它在模型保存之前發(fā)送。大多數(shù)情況下,你并不需要知道 _任何_模型何時保存 -- 只需要知道一個_特定的_模型何時保存。

在這些情況下,你可以通過注冊來接收只由特定發(fā)送器發(fā)出的信號。對于django.db.models.signals.pre_save的情況, 發(fā)送者是被保存的模型類,所以你可以認(rèn)為你只需要由某些模型發(fā)出的信號:

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函數(shù)只在MyModel實例保存時被調(diào)用。

不同的信號使用不同的對象作為他們的發(fā)送器;對于每個特定信號的細(xì)節(jié),你需要查看內(nèi)建信號的文檔。

防止重復(fù)的信號

在一些情況下,向接收者發(fā)送信號的代碼可能會執(zhí)行多次。這會使你的接收器函數(shù)被注冊多次,并且導(dǎo)致它對于同一信號事件被調(diào)用多次。

如果這樣的行為會導(dǎo)致問題(例如在任何時候模型保存時使用信號來發(fā)送郵件),傳遞一個唯一的標(biāo)識符作為 dispatch_uid參數(shù)來標(biāo)識你的接收器函數(shù)。標(biāo)識符通常是一個字符串,雖然任何可計算哈希的對象都可以。最后的結(jié)果是,對于每個唯一的dispatch_uid值,你的接收器函數(shù)都只被信號調(diào)用一次:

from django.core.signals import request_finished

request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")

定義和發(fā)送信號

你的應(yīng)用可以利用信號功能來提供自己的信號。

定義信號

class Signal([_providingargs=list])

所有信號都是 django.dispatch.Signal 的實例。providing_args是一個列表,包含參數(shù)的名字,它們由信號提供給監(jiān)聽者。理論上是這樣,但是實際上并沒有任何檢查來保證向監(jiān)聽者提供了這些參數(shù)。

例如:

import django.dispatch

pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

這段代碼聲明了pizza_done信號,它向接受者提供toppings和 size 參數(shù)。

要記住你可以在任何時候修改參數(shù)的列表,所以首次嘗試的時候不需要完全確定API。

發(fā)送信號

Django中有兩種方法用于發(fā)送信號。

Signal.``send(sender, **kwargs)

Signal.``send_robust(sender, **kwargs)

調(diào)用 Signal.send()或者Signal.send_robust()來發(fā)送信號。你必須提供sender 參數(shù)(大多數(shù)情況下它是一個類),并且可以提供盡可能多的關(guān)鍵字參數(shù)。

例如,這樣來發(fā)送我們的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), ...],它代表了被調(diào)用的接收器函數(shù)和他們的響應(yīng)值。

send()send_robust()在處理接收器函數(shù)產(chǎn)生的異常時有所不同。send()不會 捕獲任何由接收器產(chǎn)生的異常。它會簡單地讓錯誤往上傳遞。所以在錯誤產(chǎn)生的情況,不是所有接收器都會獲得通知。

send_robust()捕獲所有繼承自Python Exception類的異常,并且確保所有接收器都能得到信號的通知。如果發(fā)生了錯誤,錯誤的實例會在產(chǎn)生錯誤的接收器的二元組中返回。

New in Django 1.8:

調(diào)用send_robust()的時候,所返回的錯誤的__traceback__屬性上會帶有 traceback。

斷開信號

Signal.``disconnect([receiver=None, sender=None, weak=True, _dispatchuid=None])

調(diào)用Signal.disconnect()來斷開信號的接收器。 Signal.connect()中描述了所有參數(shù)。如果接收器成功斷開,返回 True ,否則返回False。

receiver參數(shù)表示要斷開的已注冊接收器。如果dispatch_uid 用于定義接收器,可以為None。

Changed in Django 1.8:

增加了返回的布爾值。

譯者:Django 文檔協(xié)作翻譯小組,原文:Signals

本文以 CC BY-NC-SA 3.0 協(xié)議發(fā)布,轉(zhuǎn)載請保留作者署名和文章出處。

Django 文檔協(xié)作翻譯小組人手緊缺,有興趣的朋友可以加入我們,完全公益性質(zhì)。交流群:467338606。