利用信号如何监控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 23 Python
Python创建或生成列表的操作方法
Jun 19 Python
利用python numpy+matplotlib绘制股票k线图的方法
Jun 26 Python
如何使用python把ppt转换成pdf
Jun 29 Python
Python 的字典(Dict)是如何存储的
Jul 05 Python
pymysql模块的使用(增删改查)详解
Sep 09 Python
python中的RSA加密与解密实例解析
Nov 18 Python
浅谈pytorch池化maxpool2D注意事项
Feb 18 Python
python中sort sorted reverse reversed函数的区别说明
May 11 Python
Python新手学习标准库模块命名
May 29 Python
如何用 Python 制作 GitHub 消息助手
Feb 20 Python
numpy实现RNN原理实现
Mar 02 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
如何使用FireFox插件FirePHP调试PHP
2013/07/23 PHP
yii实现图片上传及缩略图生成的方法
2014/12/04 PHP
javascript实现轮显新闻标题链接
2007/08/13 Javascript
在JavaScript中,为什么要尽可能使用局部变量?
2009/04/06 Javascript
jquery 新浪网易的评论块制作
2010/07/01 Javascript
DOM2非标准但却支持很好的几个属性小结
2012/01/21 Javascript
jquery 获取表单元素里面的值示例代码
2013/07/28 Javascript
jquery实现全选功能效果的实现代码
2016/05/05 Javascript
浅析创建javascript对象的方法
2016/05/13 Javascript
JS简单生成随机数(随机密码)的方法
2017/05/11 Javascript
JS关于刷新页面的相关总结
2018/05/09 Javascript
vue 组件中添加样式不生效的解决方法
2018/07/06 Javascript
jQuery实现简单复制json对象和json对象集合操作示例
2018/07/09 jQuery
小程序自定义组件实现城市选择功能
2018/07/18 Javascript
利用hasOwnProperty给数组去重的面试题分享
2018/11/05 Javascript
PWA介绍及快速上手搭建一个PWA应用的方法
2019/01/27 Javascript
详解js动态获取浏览器或页面等容器的宽高
2019/03/13 Javascript
如何从零开始手写Koa2框架
2019/03/22 Javascript
深入学习JavaScript 高阶函数
2019/06/11 Javascript
基于JavaScript实现单例模式
2019/10/30 Javascript
d3.js实现图形缩放平移
2019/12/19 Javascript
Vue两种组件类型:递归组件和动态组件的用法
2020/08/06 Javascript
python requests 使用快速入门
2017/08/31 Python
详解用python实现简单的遗传算法
2018/01/02 Python
python调用虹软2.0第三版的具体使用
2019/02/22 Python
Python 使用threading+Queue实现线程池示例
2019/12/21 Python
Keras 快速解决OOM超内存的问题
2020/06/11 Python
伦敦鲜花递送:Flower Station
2021/02/03 全球购物
如何在Oracle中查看各个表、表空间占用空间的大小
2015/10/31 面试题
上班迟到检讨书
2014/01/10 职场文书
幼儿园美术教学反思
2014/01/31 职场文书
体育课课后反思
2014/04/24 职场文书
期末复习计划
2015/01/19 职场文书
诚信高考倡议书
2019/06/24 职场文书
ajax请求前端跨域问题原因及解决方案
2021/10/16 Javascript
MySQL对数据表已有表进行分区表的实现
2021/11/01 MySQL