利用信号如何监控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最基本的操作字典的方法
Apr 24 Python
利用标准库fractions模块让Python支持分数类型的方法详解
Aug 11 Python
详解Python3除法之真除法、截断除法和下取整对比
May 23 Python
django框架自定义模板标签(template tag)操作示例
Jun 24 Python
python实现的分层随机抽样案例
Feb 25 Python
PyCharm License Activation激活码失效问题的解决方法(图文详解)
Mar 12 Python
windows python3安装Jupyter Notebooks教程
Apr 13 Python
Django表单提交后实现获取相同name的不同value值
May 14 Python
python如何更新包
Jun 11 Python
使用tensorflow进行音乐类型的分类
Aug 14 Python
python 爬虫如何正确的使用cookie
Oct 27 Python
基于python实现银行管理系统
Apr 20 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
IP攻击升级,程序改进以对付新的攻击
2010/11/23 PHP
ThinkPHP有变量的where条件分页实例
2014/11/03 PHP
培养自己的php编码规范
2015/09/28 PHP
PHP+MySQL存储数据常见中文乱码问题小结
2016/06/13 PHP
纯CSS3实现质感细腻丝滑按钮
2021/03/09 HTML / CSS
JS特殊函数(Function()构造函数、函数直接量)区别介绍
2013/05/19 Javascript
javaScript 动态访问JSon元素示例代码
2013/08/30 Javascript
在页面中js获取光标/鼠标的坐标及光标的像素坐标
2013/11/11 Javascript
浅谈javascript 函数属性和方法
2015/01/21 Javascript
javascript中字体浮动效果的简单实例演示
2015/11/18 Javascript
JavaScript 节流函数 Throttle 详解
2016/07/04 Javascript
Bootstrap图片轮播组件Carousel使用方法详解
2016/10/20 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
2016/12/08 Javascript
详解PHP中pathinfo()函数导致的安全问题
2017/01/05 Javascript
AngularJS解决ng-if中的ng-model值无效的问题
2017/06/21 Javascript
Vue.js devtool插件安装后无法使用的解决办法
2017/11/27 Javascript
angularJs中ng-model-options设置数据同步的方法
2018/09/30 Javascript
vue router带参数页面刷新或回退参数消失的解决方法
2019/02/27 Javascript
ES6 新增的创建数组的方法(小结)
2019/08/01 Javascript
在layui下对元素进行事件绑定的实例
2019/09/06 Javascript
[00:30]明星选手化身超级英雄!2018DOTA2亚洲邀请赛全明星赛来临!
2018/04/06 DOTA
Python简单生成8位随机密码的方法
2017/05/24 Python
Python 加密的实例详解
2017/10/09 Python
Python编程实现线性回归和批量梯度下降法代码实例
2018/01/04 Python
Django开发中复选框用法示例
2018/03/20 Python
Python使用pip安装pySerial串口通讯模块
2018/04/20 Python
Python3.5 处理文本txt,删除不需要的行方法
2018/12/10 Python
如何分离django中的媒体、静态文件和网页
2019/11/12 Python
Python Numpy库常见用法入门教程
2020/01/16 Python
实习评语
2013/12/16 职场文书
餐饮企业总经理岗位职责范文
2014/02/18 职场文书
体育教学随笔感言
2014/02/24 职场文书
股份合作协议书范本
2014/04/14 职场文书
计算机毕业大学生求职信
2014/06/26 职场文书
2015年国庆节活动总结
2015/03/23 职场文书
重阳节简报
2015/07/20 职场文书