利用信号如何监控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进阶教程之文本文件的读取和写入
Aug 29 Python
python批量提交沙箱问题实例
Oct 08 Python
python通过正则查找微博@(at)用户的方法
Mar 13 Python
Python标准库urllib2的一些使用细节总结
Mar 16 Python
Python中%r和%s的详解及区别
Mar 16 Python
Python函数式编程
Jul 20 Python
Python随机生成身份证号码及校验功能
Dec 04 Python
python计算无向图节点度的实例代码
Nov 22 Python
python实现银行实战系统
Feb 26 Python
利用OpenCV中对图像数据进行64F和8U转换的方式
Jun 03 Python
Python过滤掉numpy.array中非nan数据实例
Jun 08 Python
Python经纬度坐标转换为距离及角度的实现
Nov 01 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
phpmail类发送邮件函数代码
2012/02/20 PHP
百度ping方法使用示例 自动ping百度
2014/01/26 PHP
Laravel5.1 框架数据库操作DB运行原生SQL的方法分析
2020/01/07 PHP
PHP pthreads v3在centos7平台下的安装与配置操作方法
2020/02/21 PHP
利用location.hash实现跨域iframe自适应
2010/05/04 Javascript
JS 精确统计网站访问量的实例代码
2013/07/05 Javascript
Javascript简单实现可拖动的div
2013/10/22 Javascript
JQuery页面地址处理插件jqURL详解
2015/05/03 Javascript
详解Angular.js指令中scope类型的几种特殊情况
2017/02/21 Javascript
node.js爬虫爬取拉勾网职位信息
2017/03/14 Javascript
Vue-Router实现组件间跳转的三种方法
2017/11/07 Javascript
解决vue打包项目后刷新404的问题
2018/03/06 Javascript
layer弹出的iframe层在执行完毕后关闭当前弹出层的方法
2018/08/17 Javascript
深入理解nodejs搭建静态服务器(实现命令行)
2019/02/05 NodeJs
vue实现中部导航栏布局功能
2019/07/30 Javascript
vue 解决文本框被键盘遮住的问题
2019/11/06 Javascript
mpvue微信小程序的接口请求fly全局拦截代码实例
2019/11/13 Javascript
Angular6项目打包优化的实现方法
2019/12/15 Javascript
Python version 2.7 required, which was not found in the registry
2014/08/26 Python
使用Python3编写抓取网页和只抓网页图片的脚本
2015/08/20 Python
Python+OpenCV目标跟踪实现基本的运动检测
2018/07/10 Python
padas 生成excel 增加sheet表的实例
2018/12/11 Python
对pandas读取中文unicode的csv和添加行标题的方法详解
2018/12/12 Python
对Python3中列表乘以某一个数的示例详解
2019/07/20 Python
如何基于python实现不邻接植花
2020/05/01 Python
丝芙兰法国官网:SEPHORA法国
2016/09/01 全球购物
Myprotein台湾官方网站:全球领先的运动营养品牌
2018/12/10 全球购物
php优化查询foreach代码实例讲解
2021/03/24 PHP
教师年度考核自我鉴定
2014/01/19 职场文书
大学生秋游活动方案
2014/02/17 职场文书
《大海那边》教学反思
2014/04/09 职场文书
绘画专业自荐信
2014/07/04 职场文书
学校运动会报道稿
2014/09/23 职场文书
2015年科研工作总结范文
2015/05/13 职场文书
退休教师欢送会致辞
2015/07/31 职场文书
MySQL 外连接语法之 OUTER JOIN
2022/04/09 MySQL