Django 提供一個「信號分發器」,容許解耦的應用在框架的其它地方發生操做時會被通知到。 簡單來講,信號容許特定的sender通知一組receiver某些操做已經發生。 這在多處代碼和同一事件有關聯的狀況下頗有用。sql
django.db.models.signals
模塊定義了模型系統發送的一組信號。數據庫
Model signals pre_init # django的modal執行其構造方法前,自動觸發 post_init # django的modal執行其構造方法後,自動觸發 pre_save # django的modal對象保存前,自動觸發 post_save # django的modal對象保存後,自動觸發 pre_delete # django的modal對象刪除前,自動觸發 post_delete # django的modal對象刪除後,自動觸發 m2m_changed # django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發 class_prepared # 程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發 Management signals pre_migrate # 執行migrate命令前,自動觸發 post_migrate # 執行migrate命令後,自動觸發 Request/response signals request_started # 請求到來前,自動觸發 request_finished # 請求結束後,自動觸發 got_request_exception # 請求異常後,自動觸發 Test signals setting_changed # 使用test測試修改配置文件時,自動觸發 template_rendered # 使用test測試渲染模板時,自動觸發 Database Wrappers connection_created # 建立數據庫鏈接時,自動觸發
django.db.models.signals.pre_init
每當您實例化Django模型時,該信號都會在模型的__init__()方法的開頭髮送。django
帶有此信號的參數:後端
sender
剛建立了一個實例的模型類。
ARGS
傳遞給__init__()的位置參數列表:
kwargs
傳遞給__init__()的關鍵字參數的字典:安全
例如:服務器
from app01 import models p = models.Publisher(name='帥氣的輝哥')
發送到pre_init處理程序的參數將是:app
sender: Publisher(類自己) ARGS: [](一個空列表,由於沒有位置參數傳__init__()。) kwargs: {'name': '帥氣的輝哥'}
django.db.models.signals.pre_save
這是在模型的save()方法的開頭髮送的。框架
帶有此信號的參數:ide
sender
模型類。
instance
正在保存的實際實例。
raw
一個布爾值True若是模型按照顯示的方式保存(即當加載固定裝置時)。 不該該查詢/修改數據庫中的其餘記錄,由於數據庫可能還沒有處於一致狀態。
using
正在使用的數據庫別名。
update_fields
若是有字段被傳遞給Model.save()方法那麼就是所傳遞的字段集,不然就是None。
django.db.models.signals.post_save
像pre_save同樣,可是在save()方法的末尾發送。
帶有此信號的參數:
sender
模型類。
instance
正在保存的實際實例。
created
一個布爾值True若是建立了新記錄。
raw
一個布爾值True若是模型按照顯示的方式保存(即當加載固定裝置時)。 不該該查詢/修改數據庫中的其餘記錄,由於數據庫可能還沒有處於一致狀態。
using
正在使用的數據庫別名。
update_fields
若是有字段被傳遞給Model.save()方法那麼就是所傳遞的字段集,不然就是None。
django.db.models.signals.pre_delete
在模型的delete()方法和queryset的delete()方法的開頭髮送。
帶有此信號的參數:
sender
模型類。
instance
正在刪除的實際實例。
using
正在使用的數據庫別名。
django.db.models.signals.post_delete
像pre_delete同樣,可是在模型的delete()方法和queryset的delete()方法的末尾發送。
帶有此信號的參數:
sender
模型類。
instance
正在刪除的實際實例。請注意,該對象將再也不位於數據庫中,因此要很是當心使用此實例。
using
正在使用的數據庫別名。
django.db.models.signals.m2m_changed
django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發
在模型實例上更改了ManyToManyField時發送。 嚴格來講,這不是一個模型信號,由於它是由ManyToManyField發送的,但因爲它補充了pre_save / post_save和pre_delete / post_delete當跟蹤模型的更改時,它包括在這裏。
帶有此信號的參數:
sender
描述ManyToManyField的中間模型類。 當定義多對多字段時,此類自動建立;您可使用多對多字段上的through屬性訪問它。
instance
多對多關係更新的實例。 這能夠是sender或ManyToManyField相關的類的一個實例。
action
指示在關係上完成的更新類型的字符串。 這能夠是如下之一:
「pre_add」
在以前發送一個或多個對象被添加到關係中。
「post_add」
在以後發送一個或多個對象被添加到關係中。
「pre_remove」
在以前發送一個或多個對象從關係中刪除。
「post_remove」
在以後發送一個或多個對象從關係中刪除。
「pre_clear」
在以前發送關係被清除。
「post_clear」
以後發送關係被清除。
reverse
指示關係的哪一側被更新(即,若是它是正在被修改的正向或反向關係)。
model
添加到,從關係中刪除或從關係中清除的對象的類。
pk_set
對於pre_add,post_add,pre_remove和post_remove操做,這是一組主鍵值加入或從關係中刪除。對於pre_clear和post_clear操做,這是None。
using
正在使用的數據庫別名。
django.db.models.signals.class_prepared
程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發
每當模型類「準備」時發送 - ,一旦模型已經被定義並在Django的模型系統中註冊。 Django內部使用這個信號;它一般不會用於第三方應用程序。
因爲此信號是在應用程序註冊表羣集進程期間發送的,而且在應用註冊表徹底填充後運行AppConfig.ready(),所以沒法使用該方法鏈接接收器。 一種可能性是鏈接他們AppConfig.__init__(),注意不要導入模型或觸發對應用程序註冊表的調用。
使用此信號發送的參數:
sender
ready的model類。
django.db.models.signals.pre_migrate
在開始安裝應用程序以前,由migrate命令發送。 對於缺乏models模塊的應用,不會發送。
帶有此信號的參數:
sender
應用程序即將遷移/同步的AppConfig實例。
APP_CONFIG
與sender相同。
verbosity
指示manage.py在屏幕上打印多少信息。 有關詳細信息,請參閱--verbosity標誌。監聽pre_migrate的函數應根據該參數的值調整輸出到屏幕的內容。
interactive
若是interactive是True,則能夠安全地提示用戶在命令行中輸入內容。 若是interactive爲False,則偵聽此信號的功能不該嘗試提示任何內容。例如,當interactive爲True時,django.contrib.auth應用程序僅提示建立超級用戶。
using
命令將在其上運行的數據庫的別名。
plan
Django中的新功能1.10。
遷移計劃將用於遷移運行。 雖然該計劃不是公共API,但這在容許罕見的狀況下須要知道計劃。 一個計劃是兩個元組的列表,第一個項目是遷移類的實例,第二個項目顯示遷移是否回滾(True)或應用(False
apps
Django中的新功能1.10。
包含遷移運行前的項目狀態的Apps的實例。 應該使用它來代替全局apps註冊表來檢索要執行操做的模型。
django.db.models.signals.post_migrate
在migrate(即便不進行遷移)和flush命令的末尾發送。 對於缺乏models模塊的應用,不會發送。
此信號的處理程序不得執行數據庫模式更改,由於若是在migrate命令期間運行,則可能會致使flush命令失敗。
帶有此信號的參數:
sender
剛剛安裝的應用程序的AppConfig實例。
APP_CONFIG
與sender相同。
verbosity
指示manage.py在屏幕上打印多少信息。 有關詳細信息,請參閱--verbosity標誌。監聽post_migrate的函數應根據此參數的值調整輸出到屏幕的內容。
interactive
若是interactive是True,則能夠安全地提示用戶在命令行中輸入內容。 若是interactive爲False,則偵聽此信號的功能不該嘗試提示任何內容。例如,當interactive爲True時,django.contrib.auth應用程序僅提示建立超級用戶。
using
用於同步的數據庫別名。 默認爲default數據庫。
plan
Django中的新功能1.10。
用於遷移運行的遷移計劃。 雖然該計劃不是公共API,但這在容許罕見的狀況下須要知道計劃。 一個計劃是兩個元組的列表,第一個項目是遷移類的實例,第二個項目顯示遷移是否回滾(True)或應用(False
apps
Django中的新功能1.10。
包含遷移運行後項目狀態的Apps的實例。 應該使用它來代替全局apps註冊表來檢索要執行操做的模型。
處理請求時由核心框架發送的信號。
django.core.signals. request_started
當Django開始處理HTTP請求時發送。
帶有此信號的參數:
sender
處理程序類 - 例如django.core.handlers.wsgi.WsgiHandler - 處理該請求。
ENVIRON
environ字典提供給請求。
django.core.signals.request_finished
當Django完成向客戶端傳遞HTTP響應時發送。
帶有此信號的參數:
sender
處理程序類,如上。
django.core.signals. got_request_exception
當Django在處理傳入的HTTP請求時遇到異常時,會發送此信號。
帶有此信號的參數:
sender
處理程序類,如上。
request
HttpRequest對象。
信號只在running tests時發送。
django.test.signals.setting_changed
當經過django.test.TestCase.settings()上下文管理器或django.test.override_settings()裝飾器/上下文管理器
實際發送兩次:應用新值(「setup」)和恢復原始值(「拆除」)時。 使用enter參數來區分二者。
您還能夠從django.core.signals導入此信號,以免在非測試狀況下從django.test導入。
帶有此信號的參數:
sender
設置處理程序。
setting
設置的名稱。
value
更改後的設置值。 對於最初不存在的設置,在「拆卸」階,value爲None。
enter
一個布爾值True若是應用設置,False若是還原。
`django.test.signals.template_rendered``
測試系統呈現模板時發送。 在Django服務器的正常操做期間不發出此信號 - 它僅在測試期間可用。
帶有此信號的參數:
sender
被渲染的Template對象。
template
與發信人相同
context
模板呈現的Context。
當數據庫鏈接啓動時,由數據庫包裝器發送的信號。
django.db.backends.signals.connection_created
當數據庫包裝器與數據庫進行初始鏈接時發送。 若是您想將任何後續鏈接命令發送到SQL後端,這一點尤爲有用。
帶有此信號的參數:
sender
數據庫包裝器類 - 即django.db.backends.postgresql.DatabaseWrapper或django.db.backends.mysql.DatabaseWrapper等
connection
打開的數據庫鏈接。 這能夠在多數據庫配置中使用,以區分來自不一樣數據庫的鏈接信號。
Receiver能夠是任何Python函數或者方法:
def my_callback(sender, **kwargs): print(sender) print(kwargs) print("要保存了啊!") print('-' * 120)
一旦某個指定信號觸發,就執行我指定的receiver函數。
咱們如今的需求是,模型層一執行保存的動做就作什麼事。
因此應該是一旦觸發 pre_save 信號就執行 my_callback,對於內置的信號Django框架會自動幫咱們觸發,咱們只須要告訴它信號觸發以後作什麼事就能夠了:
pre_save.connect(my_callback)
接下來,只要涉及到ORMC鞥面的save()操做,都會自動執行我定義的my_callback函數了。
例如:
a3 = Author.objects.create(name='測試信號-做者') b3 = Book.objects.create(title='測試信號-書')
輸出:
<class 'app02.models.Author'> {'signal': <django.db.models.signals.ModelSignal object at 0x108e0d198>, 'instance': <Author: 測試信號-做者>, 'raw': False, 'using': 'default', 'update_fields': None} 要保存了啊! ------------------------------------------------------------------------------------------------------------------------ (0.001) SELECT @@SQL_AUTO_IS_NULL; args=None (0.001) INSERT INTO `app02_author` (`name`) VALUES ('測試信號-做者'); args=['測試信號-做者'] <class 'app02.models.Book'> {'signal': <django.db.models.signals.ModelSignal object at 0x108e0d198>, 'instance': <Book: 測試信號-書>, 'raw': False, 'using': 'default', 'update_fields': None} 要保存了啊! ------------------------------------------------------------------------------------------------------------------------ (0.001) INSERT INTO `app02_book` (`title`) VALUES ('測試信號-書'); args=['測試信號-書']
from django.db.models.signals import pre_save from django.dispatch import receiver @receiver(pre_save) def my_callback(sender, **kwargs): print(sender) print(kwargs) print("要保存了啊!") print('-' * 120)
上面列出來的都是Django框架內置的信號,固然咱們還能夠自定義信號。
全部信號都是 django.dispatch.Signal 的實例。 providing_args是一個列表,由信號將提供給監聽者的參數名稱組成。 理論上是這樣,可是實際上並無任何檢查來保證向監聽者提供了這些參數。
舉個例子:
from django.dispatch import Signal bath_done = Signal(providing_args=['amount', 'temperature'])
這裏定義了一個洗澡水燒好了的信號,它接受兩個參數:amount表示水量,temperature表示溫度
from django.dispatch import receiver @receiver(bath_done) def my_action(sender, **kwargs): print(sender) print(kwargs) print('脫衣服泡個澡吧!')
斯嘉麗燒好了一浴缸40度的洗澡水,杜蘭特要開喝了。
bath_done.send(sender='斯嘉麗', amount='一浴缸', temperature='40°')