利用信号如何监控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获取局域网占带宽最大3个ip的方法
Jul 09 Python
Python简单实现TCP包发送十六进制数据的方法
Apr 16 Python
Python通过RabbitMQ服务器实现交换机功能的实例教程
Jun 29 Python
Python实现字符串反转的常用方法分析【4种方法】
Sep 30 Python
python先序遍历二叉树问题
Nov 10 Python
Python3实现的爬虫爬取数据并存入mysql数据库操作示例
Jun 06 Python
Python日志模块logging基本用法分析
Aug 23 Python
Django REST framework视图的用法
Jan 16 Python
Python常见数字运算操作实例小结
Mar 22 Python
pandas 数据索引与选取的实现方法
Jun 21 Python
python 随机生成10位数密码的实现代码
Jun 27 Python
浅谈matplotlib.pyplot与axes的关系
Mar 06 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
PHP 批量删除数据的方法分析
2009/10/30 PHP
PHP创建文件,并向文件中写入数据,覆盖,追加的实现代码
2016/03/25 PHP
Yii2框架RESTful API 格式化响应,授权认证和速率限制三部分详解
2016/11/10 PHP
PHP利用DWZ.CN服务生成短网址
2019/08/11 PHP
thinkphp5框架前后端分离项目实现分页功能的方法分析
2019/10/08 PHP
简单的JS多重继承示例
2008/03/13 Javascript
Mootools 1.2教程 Fx.Morph、Fx选项和Fx事件
2009/09/15 Javascript
JavaScript Perfection kill 测试及答案
2010/03/23 Javascript
javascript限制文本框只允许输入数字(曾经与现在的方法对比)
2013/01/18 Javascript
js数组常见操作及数组与字符串相互转化实例详解
2015/11/10 Javascript
jQuery插件扩展extend的简单实现原理
2016/06/24 Javascript
JavaScript数组、json对象、eval()函数用法实例分析
2019/02/21 Javascript
[49:05]Newbee vs TNC 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python使用三角迭代计算圆周率PI的方法
2015/03/20 Python
Python multiprocessing模块中的Pipe管道使用实例
2015/04/11 Python
Python中有趣在__call__函数
2015/06/21 Python
django 修改server端口号的方法
2018/05/14 Python
python读取一个目录下所有txt里面的内容方法
2018/06/23 Python
Python正则表达式和re库知识点总结
2019/02/11 Python
Python 使用PyQt5 完成选择文件或目录的对话框方法
2019/06/27 Python
python3应用windows api对后台程序窗口及桌面截图并保存的方法
2019/08/27 Python
Python线程指南分享
2019/11/19 Python
python exit出错原因整理
2020/08/31 Python
Python爬取微信小程序Charles实现过程图解
2020/09/29 Python
pandas针对excel处理的实现
2021/01/15 Python
Marmot土拨鼠官网:美国专业户外运动品牌
2018/01/11 全球购物
商务英语本科生的自我评价分享
2013/11/15 职场文书
实用的简历自我评价
2014/03/06 职场文书
岗位安全生产责任书
2014/07/28 职场文书
如何写股份合作协议书
2014/09/11 职场文书
婚前协议书标准版
2014/10/19 职场文书
2014群众路线学习笔记
2014/11/06 职场文书
2015年会计工作总结范文
2015/05/26 职场文书
JavaScript使用canvas绘制坐标和线
2021/04/28 Javascript
MySQL窗口函数的具体使用
2021/11/17 MySQL
MySQL的InnoDB存储引擎的数据页结构详解
2022/03/03 MySQL