Django中信號signals簡單使用


在平時的開發過程中,我們會遇到一些特殊的應用場景,如果你想要在執行某種操作之前或者之后你能夠得到通知,並對其進行一些你想要的操作時,你就可以用Django中的信號(signals)。Django 提供一個“信號分發器”,允許解耦的應用在框架的其它地方發生操作時會被通知到,也就是說在特定事件發生時,可以發送一個信號去通知所有注冊了這個信號的回調,在回調里進行想要的操作處理。

一.Django內置信號

Django內置了對數據表,migrate命令,url請求相關(request/response),使用test測試,連接數據庫五大類信號。

 1 Model signals  2     pre_init                     # model執行構造方法前,觸發
 3     post_init                    # model執行構造方法后,觸發
 4     pre_save                     # model執行save對象保存前,觸發
 5     post_save                    # model執行save對象保存前,觸發
 6     pre_delete                   # model執行delete對象刪除前,觸發
 7     post_delete                  # model執行delete對象刪除前,觸發
 8     m2m_changed                  # model使用多對多字段操作第三張表前后,觸發
 9     class_prepared               # 程序啟動時,檢測已注冊的model類,對每個類,觸發
10 
11 Management signals 12     pre_migrate                  # 執行migrate前,觸發
13     post_migrate                 # 執行migrate后,觸發
14 
15 Request/response signals 16     request_started              # 請求到來前,觸發
17     request_finished             # 請求結束后,觸發
18     got_request_exception        # 請求異常后,觸發
19 
20 Test signals 21     setting_changed              # 使用test測試修改配置文件,觸發
22     template_rendered            # 使用test測試渲染模板時,觸發
23 
24 Database Wrappers 25     connection_created           # 創建數據庫連接時,觸發

1.常用內置信號參數介紹

(1)django.db.models.signals.pre_save

pre_save處理程序的參數介紹

參數名 參數介紹 sender 模型類 instance 保存的實際實例(保存后的model數據對象) raw 布爾值; True如果模型完全按照提供的方式保存。不應該查詢/修改數據庫中的其他記錄,因為數據庫可能尚未處於一致狀態 using 正在使用的數據庫別名 update_fields 要傳遞給更新的字段集model.save(),或者None 如果update_fields未傳遞給它save() 

(2)django.db.models.signals.post_save

post_save處理程序的參數介紹

參數名 參數介紹 sender 模型類 instance 保存的實際實例 created 布爾值; True如果創建了新記錄(True表示數據創建) raw 布爾值; True如果模型完全按照提供的方式保存。不應該查詢/修改數據庫中的其他記錄,因為數據庫可能尚未處於一致狀態 using 正在使用的數據庫別名 update_fields 要傳遞給更新的字段集model.save(),或者None 如果update_fields未傳遞給它save() 

(3)django.db.models.signals.pre_delete

pre_delete處理程序的參數介紹

參數名 參數介紹 sender 模型類 instance 要刪除的實際實例 using 正在使用的數據庫別名 

(4)django.db.models.signals.post_delete

post_delete處理程序的參數介紹

參數名        參數介紹 
sender       模型類 
instance     要刪除的實際實例(該對象將不再存在於數據庫中,因此請謹慎對待此實例) 
using        正在使用的數據庫別名

更多信號參數介紹請參考https://docs.djangoproject.com/zh-hans/2.1/ref/signals/

2.內置信號監聽方法

對於Django內置的信號,僅需注冊指定信號,當程序執行相應操作時,自動觸發注冊函數。當你寫好一個接收器(receiver function)用於接收到信號以后的回調處理后,就需要將接收器連接到信號,有兩種方法,手動連接,跟使用receiver裝飾器的方式。

手動連接實現方法:

from django.db.models.signals import post_delete def my_callback(sender, **kwargs): print(sender) print("信號已接收") post_delete.connect(my_callback) # 信號連接接收器,用於收到信號的回調,如果想要指定某個表對象,直接指定sender

# connect參數接收
""" receiver - 將連接到此信號的回調函數。回調函數名,不帶括號 sender - 指定從中接收信號的特定發送方。 weak - Django默認將信號處理程序存儲為弱引用。因此,如果您的接收器是本地功能,它可能被垃圾收集。為了防止這種情況,請weak=False在調用信號connect()方法時通過。 dispatch_uid - 在可能發送重復信號的情況下信號接收器的唯一標識符。 """

receiver裝飾器實現方法:

from django.dispatch import receiver from django.db.models.signals import post_delete from app.models import UCenter @receiver(post_delete, sender=UCenter)  # post_delete指定信號觸發類型,sender指定到具體對象
def delete_u2user(sender, instance, **kwargs):  # instance表示被刪除的對象
    print(sender, instance)

更多信號操作相關問題參考文檔https://docs.djangoproject.com/zh-hans/2.1/topics/signals/

二.自定義信號使用

 1.定義信號

from django.dispatch import Signal test_signal = Signal(providing_args=["name", "age"])  # 聲明一個test_signal的信號,提供給接收器name跟age兩個參數(可自定義參數)

2.注冊信號

def my_callback(sender, **kwargs): print(sender) print("信號已接收") test_signal.connect(my_callback) # 注冊信號,指定接收器為my_callback

3.觸發信號

from xxx import test_signal test_signal.send(sender='test', name='zzq', age='18')  # 觸發信號,發送name,age參數信息

當然這樣在選擇發送信號的方式有兩種一種使用Signal.send,還有一種是Signal.send_robut。

send()與send_robust()處理接收器功能引起的異常的方式不同。

send()並不能捕獲由接收器提出的任何異常; 它只是允許錯誤傳播。因此,在面對錯誤時,不是所有接收器都可以被通知信號。

send_robust()捕獲從Python Exception類派生的所有錯誤,並確保所有接收器都收到信號通知。如果發生錯誤,則會在引發錯誤的接收器的元組對中返回錯誤實例。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM