利用信号如何监控Django模型对象字段值的变化详解


Posted in Python onNovember 27, 2017

django信号系统

django自带一套信号发射系统来帮助我们在框架的不同位置传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)推送给一组接受者(receivers).信号系统在我们多处代码与同一个事件相关是特别有用.

既然是信号系统,那么必须包含以下要素:

 1. 发送者-谁发送了信号

 2. 信号-发送的信号本身

 3. 接收者-信号是发给谁的

Django 信号 (Signals) 的功能类似于 WordPress 的动作 (action),用于为项目全局增加事件的广播 (dispatch) 与接收 (receive) 机制。其中,灵活使用其内置的模型信号 (Model Signals) 的接收功能就可以监控大部分模型对象 (Model instances) 的变化。因为不需要修改模型本身的代码,在进行跨应用 (App) 监控时有低耦合的优势。

基本用法

信号的基本用法官方文档上的 主题 与 参考 上已经有详细描述。本文只提几个要点(本文环境:Django 1.8 & Python 3.4):

代码组织

官方推荐在应用目录下新增一个 signals.py 文件,同时参考官方文档的 应用配置 节中自定义应用配置 (AppConfig) ,重载应用配置类的 run 方法,在该方法内调用 from . import signals

接收信号

推荐使用 django.dispatch.receiver 这个装饰器进行信号的接收:

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)

从代码可读性的角度来讲,建议一个接收函数只做一件事。

监控特定字段 (field) 值的变化

从上一段代码可以知道,通过接收模型 post_save 信号,可以得知发生了保存模型对象的操作,并且还可以区分出是创建了模型对象还是更新了模型对象。然而,模型信号并没有提供针对特定字段值变化的广播功能,虽然该信号提供了 update_fields 参数,但是并不能证明在该参数中的字段名的字段值一定发生了变化,所以我们要采用一个结合 post_init 信号的变通方法。

举一个例子:当学生名字发生改变之后发布一条公告。

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 信号的时候,在模型对象中缓存当前的字段值;在模型广播 post_save (或 pre_save )的时候,比较该模型对象的当前的字段值与缓存的字段值,如果不相同则认为该字段值发生了变化。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。  

Python 相关文章推荐
python模拟鼠标拖动操作的方法
Mar 11 Python
Python的Django框架中forms表单类的使用方法详解
Jun 21 Python
Python socket网络编程TCP/IP服务器与客户端通信
Jan 05 Python
pygame游戏之旅 按钮上添加文字的方法
Nov 21 Python
python调用staf自动化框架的方法
Dec 26 Python
python实现windows壁纸定期更换功能
Jan 21 Python
python 统计文件中的字符串数目示例
Dec 24 Python
Keras Convolution1D与Convolution2D区别说明
May 22 Python
Django自带用户认证系统使用方法解析
Nov 12 Python
Python request post上传文件常见要点
Nov 20 Python
Python 可迭代对象 iterable的具体使用
Aug 07 Python
Python利用zhdate模块实现农历日期处理
Mar 31 Python
深入理解Python中range和xrange的区别
Nov 26 #Python
PyCharm在win10的64位系统安装实例
Nov 26 #Python
python shell根据ip获取主机名代码示例
Nov 25 #Python
python自动裁剪图像代码分享
Nov 25 #Python
分享一个简单的python读写文件脚本
Nov 25 #Python
python之virtualenv的简单使用方法(必看篇)
Nov 25 #Python
python多进程实现进程间通信实例
Nov 24 #Python
You might like
在字符串中把网址改成超级链接
2006/10/09 PHP
PHP数据集构建JSON格式及新数组的方法
2012/11/07 PHP
PHP变量内存分配问题记录整理
2013/11/27 PHP
php中count获取多维数组长度的方法
2014/11/03 PHP
Laravel 实现Controller向blade前台模板赋值的四种方式小结
2019/10/22 PHP
JavaScript 三种不同位置代码的写法
2009/10/25 Javascript
JavaScript 格式字符串的应用
2010/03/29 Javascript
基于jQuery的Tab选项框效果代码(插件)
2011/03/01 Javascript
javascript动态加载实现方法一
2012/08/22 Javascript
JS阻止冒泡事件以及默认事件发生的简单方法
2014/01/17 Javascript
动态的创建一个元素createElement及删除一个元素
2014/01/24 Javascript
JS实现的图片预览插件与用法示例【不上传图片】
2016/11/25 Javascript
vue 挂载路由到头部导航的方法
2017/11/13 Javascript
iview table render集成switch开关的实例
2018/03/14 Javascript
通过jquery toggleClass()属性制作文章段落更改背景颜色
2018/05/21 jQuery
JS实现的点击按钮图片上下滚动效果示例
2019/01/28 Javascript
谈谈JavaScript中super(props)的重要性
2019/02/12 Javascript
新手入门带你学习JavaScript引擎运行原理
2019/06/24 Javascript
Vue 路由间跳转和新开窗口的方式(query、params)
2019/12/25 Javascript
通过实例解析JavaScript常用排序算法
2020/09/02 Javascript
Python内存读写操作示例
2018/07/18 Python
Python中numpy模块常见用法demo实例小结
2019/03/16 Python
Python代码使用 Pyftpdlib实现FTP服务器功能
2019/07/22 Python
python字符串替换re.sub()实例解析
2020/02/09 Python
用Python做一个久坐提醒小助手的示例代码
2020/02/10 Python
python+pygame实现坦克大战小游戏的示例代码(可以自定义子弹速度)
2020/08/11 Python
python 三种方法实现对Excel表格的读写
2020/11/19 Python
快速创建python 虚拟环境
2020/11/28 Python
Html5踩坑记之mandMobile使用小记
2020/04/02 HTML / CSS
美国艺术和工艺品商店:Hobby Lobby
2020/12/09 全球购物
英国发展最快的在线超市之一:Click Marketplace
2021/02/15 全球购物
个人自荐书
2013/12/20 职场文书
上课说话检讨书500字
2014/11/01 职场文书
怎样写辞职信
2015/02/27 职场文书
搞笑婚前保证书
2015/02/28 职场文书
Vue.js 带下拉选项的输入框(Textbox with Dropdown)组件
2021/04/17 Vue.js