利用信號如何監(jiān)控Django模型對象字段值的變化詳解
django信號系統(tǒng)
django自帶一套信號發(fā)射系統(tǒng)來幫助我們在框架的不同位置傳遞信息.也就是說,當(dāng)某一事件發(fā)生時(shí),信號系統(tǒng)可以允許一個或多個發(fā)送者(senders)將通知或信號(signals)推送給一組接受者(receivers).信號系統(tǒng)在我們多處代碼與同一個事件相關(guān)是特別有用.
既然是信號系統(tǒng),那么必須包含以下要素:
1. 發(fā)送者-誰發(fā)送了信號
2. 信號-發(fā)送的信號本身
3. 接收者-信號是發(fā)給誰的
Django 信號 (Signals) 的功能類似于 WordPress 的動作 (action),用于為項(xiàng)目全局增加事件的廣播 (dispatch) 與接收 (receive) 機(jī)制。其中,靈活使用其內(nèi)置的模型信號 (Model Signals) 的接收功能就可以監(jiān)控大部分模型對象 (Model instances) 的變化。因?yàn)椴恍枰薷哪P捅旧淼拇a,在進(jìn)行跨應(yīng)用 (App) 監(jiān)控時(shí)有低耦合的優(yōu)勢。
基本用法
信號的基本用法官方文檔上的 主題 與 參考 上已經(jīng)有詳細(xì)描述。本文只提幾個要點(diǎn)(本文環(huán)境:Django 1.8 & Python 3.4):
代碼組織
官方推薦在應(yīng)用目錄下新增一個 signals.py 文件,同時(shí)參考官方文檔的 應(yīng)用配置 節(jié)中自定義應(yīng)用配置 (AppConfig) ,重載應(yīng)用配置類的 run 方法,在該方法內(nèi)調(diào)用 from . import signals
接收信號
推薦使用 django.dispatch.receiver 這個裝飾器進(jìn)行信號的接收:
from django.db.models import signals from django.dispatch import receiver from students.models import Student from .models import Announcement @receiver(signals.post_save, sender=Student) def welcome_student(instance, created, **kwargs): if created: Announcement.objects.create(content='Welcome new student ' + instance.name)
從代碼可讀性的角度來講,建議一個接收函數(shù)只做一件事。
監(jiān)控特定字段 (field) 值的變化
從上一段代碼可以知道,通過接收模型 post_save 信號,可以得知發(fā)生了保存模型對象的操作,并且還可以區(qū)分出是創(chuàng)建了模型對象還是更新了模型對象。然而,模型信號并沒有提供針對特定字段值變化的廣播功能,雖然該信號提供了 update_fields 參數(shù),但是并不能證明在該參數(shù)中的字段名的字段值一定發(fā)生了變化,所以我們要采用一個結(jié)合 post_init 信號的變通方法。
舉一個例子:當(dāng)學(xué)生名字發(fā)生改變之后發(fā)布一條公告。
from django.db.models import signals from django.dispatch import receiver from students.models import Student from .models import Announcement @receiver(signals.post_init, sender=Student) def welcome_student(instance, **kwargs): instance.__original_name = instance.name @receiver(signals.post_save, sender=Student) def welcome_student(instance, created, **kwargs): if not created and instance.__original_name != instance.name: Announcement.objects.create(content= 'Student %s has renamed to %s' % (instance.__original_name, instance.name))
簡單的說就是在該模型廣播 post_init 信號的時(shí)候,在模型對象中緩存當(dāng)前的字段值;在模型廣播 post_save (或 pre_save )的時(shí)候,比較該模型對象的當(dāng)前的字段值與緩存的字段值,如果不相同則認(rèn)為該字段值發(fā)生了變化。
總結(jié)
以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,如果有疑問大家可以留言交流,謝謝大家對腳本之家的支持。
相關(guān)文章
pymysql之cur.fetchall() 和cur.fetchone()用法詳解
這篇文章主要介紹了pymysql之cur.fetchall() 和cur.fetchone()用法詳解,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-05-05
python定時(shí)任務(wù)timeloop庫用法實(shí)例詳解
有些時(shí)候我們需要每隔一段時(shí)間就要執(zhí)行一段程序,或者是往復(fù)循環(huán)執(zhí)行某一個任務(wù),下面這篇文章主要給大家介紹了關(guān)于python定時(shí)任務(wù)timeloop庫用法的相關(guān)資料,需要的朋友可以參考下2023-01-01
Dlib+OpenCV深度學(xué)習(xí)人臉識別的方法示例
這篇文章主要介紹了Dlib+OpenCV深度學(xué)習(xí)人臉識別的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-05-05
Python實(shí)現(xiàn)搜索算法的實(shí)例代碼
這篇文章主要介紹了Python實(shí)現(xiàn)搜索算法,文中通過實(shí)例代碼給大家分享高級搜索算法的想法,分為線性搜索和插值搜索,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-01-01
分析Python感知線程狀態(tài)的解決方案之Event與信號量
本文主要介紹了如何感知線程狀態(tài)、如何停止一個線程、線程之間的Event用法2021-06-06
Python實(shí)現(xiàn)為Excel中每個單元格計(jì)算其在文件中的平均值
這篇文章主要為大家詳細(xì)介紹了如何基于Python語言實(shí)現(xiàn)對大量不同的Excel文件加以跨文件、逐單元格平均值計(jì)算,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-10-10
Python利用request庫實(shí)現(xiàn)翻譯接口
這篇文章主要為大家詳細(xì)介紹了Python如何利用request庫打造自己的翻譯接口,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2023-04-04
數(shù)據(jù)可視化Pyecharts的實(shí)際使用方式
這篇文章主要介紹了數(shù)據(jù)可視化Pyecharts的實(shí)際使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2024-04-04

