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):
pass
def callback3(sender, **kwargs):
pass
post_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.dispatch
my_signal = django.dispatch.Signal(providing_args=[‘arg1‘, ‘arg2‘])
# providing_args中的參數自定義
在項目的__init__.py
中註冊自定義信號:
from my_signal import my_signal
def callback(sender, **kwargs):
pass
my_signal.connect(callback)
在需要用到自定義信號的地方,導入自定義信號,給它發送信號:
from my_signal import my_signal
my_signal.send(sender=‘‘, arg1=‘‘, arg2=‘‘)
Django 信號