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

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

信號(hào)

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

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

關(guān)于完整列表以及每個(gè)信號(hào)的完整解釋,請(qǐng)見內(nèi)建信號(hào)的文檔

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

監(jiān)聽信號(hào)

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

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

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

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

接收器函數(shù)

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

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

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

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

這是錯(cuò)誤的 -- 實(shí)際上,如果你這么做了,Django會(huì)拋出異常。這是因?yàn)闊o論什么時(shí)候信號(hào)中添加了參數(shù),你的接收器都必須能夠處理這些新的參數(shù)。

連接接收器函數(shù)

有兩種方法可以將一個(gè)接收器連接到信號(hào)。你可以采用手動(dòng)連接的方法:

from django.core.signals import request_finished

request_finished.connect(my_callback)

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

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ù)會(huì)在每次請(qǐng)求結(jié)束時(shí)調(diào)用。

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

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

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

Changed in Django 1.7:

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

注意

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

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

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

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

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實(shí)例保存時(shí)被調(diào)用。

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

防止重復(fù)的信號(hào)

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

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

from django.core.signals import request_finished

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

定義和發(fā)送信號(hào)

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

定義信號(hào)

class Signal([_providingargs=list])

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

例如:

import django.dispatch

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

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

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

發(fā)送信號(hào)

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

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

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

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

例如,這樣來發(fā)送我們的pizza_done信號(hào):

class PizzaStore(object):
    ...

    def send_pizza(self, toppings, size):
        pizza_done.send(sender=self.__class__, toppings=toppings, size=size)
        ...

send()send_robust()都會(huì)返回一個(gè)含有二元組的列表 [(receiver, response), ...],它代表了被調(diào)用的接收器函數(shù)和他們的響應(yīng)值。

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

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

New in Django 1.8:

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

斷開信號(hào)

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

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

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

Changed in Django 1.8:

增加了返回的布爾值。

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

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

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

上一篇:安全下一篇:Django模版語言