Django 信号
Django 信號
Django提供一種信號機制,一些動作發生時,會觸發信號,然后監聽了這個信號的函數就會被執行。比如,實現數據庫每寫入一條數據,寫一條日志。要實現這個需求,可以通過全局的中間件來做,但是利用Django的信號機制會更靈活。中間件只作用在請求進來和響應出去時,而信號的散布范圍更廣。
我們先看看Django內置了哪些信號:
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命令前,自動觸發
Request/response signals
request_started # 請求到來前,自動觸發
request_finished # 請求結束后,自動觸發
got_request_exception # 請求異常后,自動觸發
Test signals
setting_changed # 使用test測試修改配置文件時,自動觸發
Database Wrappers
connection_created # 創建數據庫連接時,自動觸發
那么如何使用信號呢?
導入信號 –> 將回調函數注冊到信號上 ;
注意,只有執行了注冊代碼,才能在信號發生時,執行注冊的函數。因此,為了能在服務啟動時,執行注冊代碼,應該將注冊信號的操作寫在項目的__init__.py中
from django.db.models.signals import post_save # 導入信號def callback1(sender, **kwargs): # 定義回調函數, 作為信號的接收者print('create a new user')print(sender, kwargs)def callback2(sender, **kwargs):passdef callback3(sender, **kwargs):passpost_save.connect(callback1) # 我們也可以為信號注冊多個函數 # post_save.connect(callback2) # post_save.connect(callback3)下面在視圖中往數據庫新增一條記錄:
def add(request):u = UserInfo(name='sb',pwd='123')u.save()return HttpResponse('save ok')通過瀏覽器訪問http://127.0.0.1:8000/add/來執行add視圖,models.UserInfo觸發信號,回調函數收到信號,執行。查看打印結果:
create a new user <class 'app01.models.UserInfo'> {'signal': <django.db.models.signals.ModelSignal object at 0x000001CA5118DDA0>, 'instance': <UserInfo: UserInfo object>, 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}回調的方式注冊信號,我們也可以通過裝飾器的方式:
from django.db.models.signals import post_save from django.dispatch import receiver@receiver(post_save) def callback(sender, **kwargs):pass自定義信號
我們可以將自定義的信號單獨寫在一個腳本:
import django.dispatchmy_signal = django.dispatch.Signal(providing_args=['arg1', 'arg2']) # providing_args中的參數自定義在項目的__init__.py中注冊自定義信號:
from my_signal import my_signaldef callback(sender, **kwargs):passmy_signal.connect(callback)在需要用到自定義信號的地方,導入自定義信號,給它發送信號:
from my_signal import my_signal my_signal.send(sender='', arg1='', arg2='') 新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!總結
- 上一篇: 转:word2vec 中的数学原理详解
- 下一篇: 记录hadoop3.2.2出现Could