Django中提供了"信號調度",用於在框架執行操作時解耦,當某些動作發生的時候,系統會根據信號定義的函數執行相應的操作
一.Django中內置的 signal 類型主要包含以下幾種
1.Model_signals
pre_init # Django中的model對象執行其構造方法前,自動觸發 post_init # Django中的model對象執行其構造方法后,自動觸發 pre_save # Django中的model對象保存前,自動觸發 post_save # Django中的model對象保存后,自動觸發 pre_delete # Django中的model對象刪除前,自動觸發 post_delete # Django中的model對象刪除后,自動觸發 m2m_changed # Django中的model對象使用m2m字段操作數據庫的第三張表(add,remove,clear,update),自動觸發 class_prepared # 程序啟動時,檢測到已注冊的model類,對於每一個類,自動觸發
2.Managemeng_signals
pre_migrate # 執行migrate命令前,自動觸發 post_migrate # 執行migrate命令后,自動觸發
3.Request/response_signals
request_started # 請求到來前,自動觸發 request_finished # 請求結束后,自動觸發 got_request_exception # 請求異常時,自動觸發
4.Test_signals
setting_changed # 配置文件改變時,自動觸發 template_rendered # 模板執行渲染操作時,自動觸發
5.Datebase_Wrapperd
connection_created # 創建數據庫連接時,自動觸發
二.對於Django內置的信號,僅需注冊指定信號,當程序執行相應操作時,系統會自動觸發注冊函數
1.以 post_save 信號類型進行說明:
在相應的應用(app)目錄下的__init__.py文件中進行定義,(可以另外創建一個.py文件, 再在__init__.py文件導入該文件)
# 導包
from django.db.models.signals import post_save
from django.dispatch import receiver
# 導入模型
from .models import MyModel
# django.db.models.signals.pre_save 在某個Model保存之前調用
# django.db.models.signals.post_save 在某個Model保存之后調用
# django.db.models.signals.pre_delete 在某個Model刪除之前調用
# django.db.models.signals.post_delete 在某個Model刪除之后調用
# django.core.signals.request_started 在建立Http請求時發送
# django.core.signals.request_finished 在關閉Http請求時發送
創建函數,監聽信號, 當信號觸發時,進行函數的調用
# 將函數進行注冊,聲明為回調函數, 第一個參數為信號類型, 如果聲明sender , 那么接收器只會接收這個sender的信號, 這里聲明為只接收MyModel模型的信號
# post_save 在某個Model保存之后調用, 對於每個唯一的dispatch_uid,接收器都只被信號調用一次
@receiver(post_save, sender=MyModel, dispatch_uid="my_unique_identifier")
def my_handler(sender, instance, **kwargs): #參數:**kwargs必須.第一個參數必須為sender, 當信號類型為 Model_signals, 接收到的第二個參數為模型對象. print(instance.name) # 可以直接使用這個模型實例對象進行操作
print("hello world")
2. request_finished 信號
from django.core.signals import request_finished from django.dispatch import receive @receiver(request_finished) defmy_callback(sender, **kwargs): print"Request finished!"
這樣配置之后,django接收到所有的request請求結束以后,都會調用這個接收器回調函數.
三.進一步補充默認的signals及其參數
模型的(django/db/models/signal.py)
from django.dispatch import Signal class_prepared = Signal(providing_args=["class"]) pre_init = Signal(providing_args=["instance", "args", "kwargs"], use_caching=True) post_init = Signal(providing_args=["instance"], use_caching=True) pre_save = Signal(providing_args=["instance", "raw", "using", "update_fields"], use_caching=True) post_save = Signal(providing_args=["instance", "raw", "created", "using", "update_fields"], use_caching=True) pre_delete = Signal(providing_args=["instance", "using"], use_caching=True) post_delete = Signal(providing_args=["instance", "using"], use_caching=True) pre_syncdb = Signal(providing_args=["app", "create_models", "verbosity", "interactive", "db"]) post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive", "db"]) m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set", "using"], use_caching=True)
用戶登錄的(django/contrib/auth/signals.py)
from django.dispatch import Signal user_logged_in = Signal(providing_args=['request', 'user']) user_login_failed = Signal(providing_args=['credentials']) user_logged_out = Signal(providing_args=['request', 'user'])
關於request請求的(django/core/signals.py)
from django.dispatch import Signal request_started = Signal() request_finished = Signal() got_request_exception = Signal(providing_args=["request"])
數據庫連接的(django/db/backends/signals.py)
from django.dispatch import Signal connection_created = Signal(providing_args=["connection"])
四.在個人的實際項目開發中,使用得比較多的信號類型就是django/db/models/signal.py(如:用戶注冊成功后發送郵件或進行其他操作)以及用戶登錄的django/contrib/auth/signals.py(用戶登錄成功后,給用戶發送消息). 如果內置的信號類型無法滿足需求,可以進行自定義信號, 這里不再贅述.