利用信号如何监控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随机生成一个6位的验证码代码分享
Mar 24 Python
Python实现读取TXT文件数据并存进内置数据库SQLite3的方法
Aug 08 Python
python使用super()出现错误解决办法
Aug 14 Python
[原创]python爬虫(入门教程、视频教程)
Jan 08 Python
Python基于lxml模块解析html获取页面内所有叶子节点xpath路径功能示例
May 16 Python
python实现海螺图片的方法示例
May 12 Python
numpy ndarray 按条件筛选数组,关联筛选的例子
Nov 26 Python
Python matplotlib 绘制双Y轴曲线图的示例代码
Jun 12 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
Jul 07 Python
python使用建议与技巧分享(一)
Aug 17 Python
Python爬虫+tkinter界面实现历史天气查询的思路详解
Feb 22 Python
Python机器学习之PCA降维算法详解
May 19 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
从网上搜到的phpwind 0day的代码
2006/12/07 PHP
php使用mb_check_encoding检查字符串在指定的编码里是否有效
2013/11/07 PHP
typecho插件编写教程(五):核心代码
2015/05/28 PHP
PHP中类的自动加载的方法
2017/03/17 PHP
提高Laravel应用性能方法详解
2019/06/24 PHP
Jquery 最近浏览过的商品的功能实现代码
2010/05/14 Javascript
jquery 操作日期、星期、元素的追加的实现代码
2012/02/07 Javascript
Javascript中this的用法详解
2014/09/22 Javascript
用js编写的简单的计算器代码程序
2015/08/04 Javascript
动态加载JavaScript文件的两种方法
2016/04/22 Javascript
JavaScript程序中的流程控制语句用法总结
2016/05/23 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
详解nodejs 文本操作模块-fs模块(四)
2016/12/22 NodeJs
JS实现问卷星自动填问卷脚本并在两秒自动提交功能
2020/06/17 Javascript
一个Java程序猿眼中的前后端分离以及Vue.js入门(推荐)
2019/04/19 Javascript
vue 通过 Prop 向子组件传递数据的实现方法
2020/10/30 Javascript
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
[55:44]完美世界DOTA2联赛决赛 FTD vs Phoenix 第二场 11.08
2020/11/11 DOTA
python实现决策树C4.5算法详解(在ID3基础上改进)
2017/05/31 Python
pip matplotlib报错equired packages can not be built解决
2018/01/06 Python
python 读入多行数据的实例
2018/04/19 Python
使用Django启动命令行及执行脚本的方法
2018/05/29 Python
Django 静态文件配置过程详解
2019/07/23 Python
手把手教你pycharm专业版安装破解教程(linux版)
2019/09/26 Python
解决pyshp UnicodeDecodeError的问题
2019/12/06 Python
会计专业应届生自荐信
2014/02/07 职场文书
酒店总经理助理职责
2014/02/12 职场文书
《十六年前的回忆》教学反思
2014/02/14 职场文书
网上祭先烈心得体会
2014/09/01 职场文书
公共艺术专业自荐信
2014/09/01 职场文书
单方离婚协议书范本(2014版)
2014/09/30 职场文书
安全先进班组材料
2014/12/26 职场文书
2015教师个人工作总结范文
2015/03/31 职场文书
2015大学迎新标语
2015/07/16 职场文书
Java移除无效括号的方法实现
2021/08/07 Java/Android
WINDOWS下安装mysql 8.x 的方法图文教程
2022/04/19 MySQL