Django中信號(hào)signals的簡單使用方法
正文
在平時(shí)的開發(fā)過程中,我們會(huì)遇到一些特殊的應(yīng)用場(chǎng)景,如果你想要在執(zhí)行某種操作之前或者之后你能夠得到通知,并對(duì)其進(jìn)行一些你想要的操作時(shí),你就可以用Django中的信號(hào)(signals)。Django 提供一個(gè)“信號(hào)分發(fā)器”,允許解耦的應(yīng)用在框架的其它地方發(fā)生操作時(shí)會(huì)被通知到,也就是說在特定事件發(fā)生時(shí),可以發(fā)送一個(gè)信號(hào)去通知所有注冊(cè)了這個(gè)信號(hào)的回調(diào),在回調(diào)里進(jìn)行想要的操作處理。
一.Django內(nèi)置信號(hào)
Django內(nèi)置了對(duì)數(shù)據(jù)表,migrate命令,url請(qǐng)求相關(guān)(request/response),使用test測(cè)試,連接數(shù)據(jù)庫五大類信號(hào)。
Model signals pre_init # model執(zhí)行構(gòu)造方法前,觸發(fā) post_init # model執(zhí)行構(gòu)造方法后,觸發(fā) pre_save # model執(zhí)行save對(duì)象保存前,觸發(fā) post_save # model執(zhí)行save對(duì)象保存前,觸發(fā) pre_delete # model執(zhí)行delete對(duì)象刪除前,觸發(fā) post_delete # model執(zhí)行delete對(duì)象刪除前,觸發(fā) m2m_changed # model使用多對(duì)多字段操作第三張表前后,觸發(fā) class_prepared # 程序啟動(dòng)時(shí),檢測(cè)已注冊(cè)的model類,對(duì)每個(gè)類,觸發(fā) Management signals pre_migrate # 執(zhí)行migrate前,觸發(fā) post_migrate # 執(zhí)行migrate后,觸發(fā) Request/response signals request_started # 請(qǐng)求到來前,觸發(fā) request_finished # 請(qǐng)求結(jié)束后,觸發(fā) got_request_exception # 請(qǐng)求異常后,觸發(fā) Test signals setting_changed # 使用test測(cè)試修改配置文件,觸發(fā) template_rendered # 使用test測(cè)試渲染模板時(shí),觸發(fā) Database Wrappers connection_created # 創(chuàng)建數(shù)據(jù)庫連接時(shí),觸發(fā)
1.常用內(nèi)置信號(hào)參數(shù)介紹
(1)django.db.models.signals.pre_save
pre_save處理程序的參數(shù)介紹
參數(shù)名 參數(shù)介紹
sender 模型類
instance 保存的實(shí)際實(shí)例(保存后的model數(shù)據(jù)對(duì)象)
raw 布爾值; True如果模型完全按照提供的方式保存。不應(yīng)該查詢/修改數(shù)據(jù)庫中的其他記錄,因?yàn)閿?shù)據(jù)庫可能尚未處于一致狀態(tài)
using 正在使用的數(shù)據(jù)庫別名
update_fields 要傳遞給更新的字段集model.save(),或者None 如果update_fields未傳遞給它save()
(2)django.db.models.signals.post_save
post_save處理程序的參數(shù)介紹
參數(shù)名 參數(shù)介紹
sender 模型類
instance 保存的實(shí)際實(shí)例
created 布爾值; True如果創(chuàng)建了新記錄(True表示數(shù)據(jù)創(chuàng)建)
raw 布爾值; True如果模型完全按照提供的方式保存。不應(yīng)該查詢/修改數(shù)據(jù)庫中的其他記錄,因?yàn)閿?shù)據(jù)庫可能尚未處于一致狀態(tài)
using 正在使用的數(shù)據(jù)庫別名
update_fields 要傳遞給更新的字段集model.save(),或者None 如果update_fields未傳遞給它save()
(3)django.db.models.signals.pre_delete
pre_delete處理程序的參數(shù)介紹
參數(shù)名 參數(shù)介紹
sender 模型類
instance 要?jiǎng)h除的實(shí)際實(shí)例
using 正在使用的數(shù)據(jù)庫別名
(4)django.db.models.signals.post_delete
post_delete處理程序的參數(shù)介紹
參數(shù)名 參數(shù)介紹
sender 模型類
instance 要?jiǎng)h除的實(shí)際實(shí)例(該對(duì)象將不再存在于數(shù)據(jù)庫中,因此請(qǐng)謹(jǐn)慎對(duì)待此實(shí)例)
using 正在使用的數(shù)據(jù)庫別名
更多信號(hào)參數(shù)介紹請(qǐng)參考https://docs.djangoproject.com/zh-hans/2.1/ref/signals/
2.內(nèi)置信號(hào)監(jiān)聽方法
對(duì)于Django內(nèi)置的信號(hào),僅需注冊(cè)指定信號(hào),當(dāng)程序執(zhí)行相應(yīng)操作時(shí),自動(dòng)觸發(fā)注冊(cè)函數(shù)。當(dāng)你寫好一個(gè)接收器(receiver function)用于接收到信號(hào)以后的回調(diào)處理后,就需要將接收器連接到信號(hào),有兩種方法,手動(dòng)連接,跟使用receiver裝飾器的方式。
手動(dòng)連接實(shí)現(xiàn)方法:
from django.db.models.signals import post_delete def my_callback(sender, **kwargs): print(sender) print("信號(hào)已接收") post_delete.connect(my_callback) # 信號(hào)連接接收器,用于收到信號(hào)的回調(diào),如果想要指定某個(gè)表對(duì)象,直接指定sender # connect參數(shù)接收 """ receiver - 將連接到此信號(hào)的回調(diào)函數(shù)?;卣{(diào)函數(shù)名,不帶括號(hào) sender - 指定從中接收信號(hào)的特定發(fā)送方。 weak - Django默認(rèn)將信號(hào)處理程序存儲(chǔ)為弱引用。因此,如果您的接收器是本地功能,它可能被垃圾收集。為了防止這種情況,請(qǐng)weak=False在調(diào)用信號(hào)connect()方法時(shí)通過。 dispatch_uid - 在可能發(fā)送重復(fù)信號(hào)的情況下信號(hào)接收器的唯一標(biāo)識(shí)符。 """
receiver裝飾器實(shí)現(xiàn)方法:
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指定信號(hào)觸發(fā)類型,sender指定到具體對(duì)象 def delete_u2user(sender, instance, **kwargs): # instance表示被刪除的對(duì)象 print(sender, instance)
更多信號(hào)操作相關(guān)問題參考文檔https://docs.djangoproject.com/zh-hans/2.1/topics/signals/
二.自定義信號(hào)使用
1.定義信號(hào)
from django.dispatch import Signal test_signal = Signal(providing_args=["name", "age"]) # 聲明一個(gè)test_signal的信號(hào),提供給接收器name跟age兩個(gè)參數(shù)(可自定義參數(shù))
2.注冊(cè)信號(hào)
def my_callback(sender, **kwargs): print(sender) print("信號(hào)已接收") test_signal.connect(my_callback) # 注冊(cè)信號(hào),指定接收器為my_callback
3.觸發(fā)信號(hào)
from xxx import test_signal test_signal.send(sender='test', name='zzq', age='18') # 觸發(fā)信號(hào),發(fā)送name,age參數(shù)信息
當(dāng)然這樣在選擇發(fā)送信號(hào)的方式有兩種一種使用Signal.send,還有一種是Signal.send_robut。
send()與send_robust()處理接收器功能引起的異常的方式不同。
send()并不能捕獲由接收器提出的任何異常; 它只是允許錯(cuò)誤傳播。因此,在面對(duì)錯(cuò)誤時(shí),不是所有接收器都可以被通知信號(hào)。
send_robust()捕獲從Python Exception類派生的所有錯(cuò)誤,并確保所有接收器都收到信號(hào)通知。如果發(fā)生錯(cuò)誤,則會(huì)在引發(fā)錯(cuò)誤的接收器的元組對(duì)中返回錯(cuò)誤實(shí)例。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,謝謝大家對(duì)腳本之家的支持。
相關(guān)文章
分解oracle存儲(chǔ)過程或函數(shù)調(diào)試過程步驟
這篇文章主要介紹了調(diào)試oracle存儲(chǔ)過程或函數(shù)過程步驟,文中附含詳細(xì)的圖文操作步驟,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-09-09python實(shí)現(xiàn)月食效果實(shí)例代碼
在本文里小編給大家整理了關(guān)于python實(shí)現(xiàn)月食效果的相關(guān)實(shí)例內(nèi)容以及對(duì)應(yīng)代碼,有興趣的朋友們學(xué)習(xí)下。2019-06-06從零學(xué)Python之入門(五)縮進(jìn)和選擇
空白在Python中是重要的。事實(shí)上行首的空白是重要的。它稱為縮進(jìn)。在邏輯行首的空白(空格和制表符)用來決定邏輯行的縮進(jìn)層次,從而用來決定語句的分組。2014-05-05python中Switch/Case實(shí)現(xiàn)的示例代碼
本篇文章主要介紹了python中Switch/Case實(shí)現(xiàn)的示例代碼,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-11-11Python使用matplotlib給柱狀圖添加數(shù)據(jù)標(biāo)簽bar_label()
這篇文章主要介紹了Python使用matplotlib給柱狀圖添加數(shù)據(jù)標(biāo)簽bar_label(),記錄如何用使用matplotlib給柱狀圖添加數(shù)據(jù)標(biāo)簽,是以matplotlib.pyplot.bar_label()為例,需要的朋友可以參考一下2022-03-03python數(shù)據(jù)結(jié)構(gòu)之列表和元組的詳解
這篇文章主要介紹了python數(shù)據(jù)結(jié)構(gòu)之列表和元組的詳解的相關(guān)資料,希望通過本文能幫助到大家,讓大家徹底理解掌握這部分內(nèi)容,需要的朋友可以參考下2017-09-09opencv python截取圓形區(qū)域的實(shí)現(xiàn)
本文主要介紹了opencv python截取圓形區(qū)域的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08