利用信号如何监控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实现代码行数统计示例分享
Feb 10 Python
python基础教程之基本数据类型和变量声明介绍
Aug 29 Python
简单谈谈python中的多进程
Nov 06 Python
详解django中自定义标签和过滤器
Jul 03 Python
PyQt5+requests实现车票查询工具
Jan 21 Python
python实现连连看辅助(图像识别)
Mar 25 Python
Django实现web端tailf日志文件功能及实例详解
Jul 28 Python
python实现一个函数版的名片管理系统过程解析
Aug 27 Python
Python 异常处理Ⅳ过程图解
Oct 18 Python
python如何把字符串类型list转换成list
Feb 18 Python
Django Admin设置应用程序及模型顺序方法详解
Apr 01 Python
Python时间操作之pytz模块使用详解
Jun 14 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中jpgraph类库的使用介绍
2013/08/08 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
jQuery队列控制方法详解queue()/dequeue()/clearQueue()
2010/12/02 Javascript
使用jquery读取html5 localstorage的值的方法
2013/01/04 Javascript
获取select元素被选中的文本内容的js代码
2014/01/29 Javascript
javascript中声明函数的方法及调用函数的返回值
2014/07/22 Javascript
ExpressJS入门实例
2015/01/14 Javascript
js实现无限级树形导航列表效果代码
2015/09/23 Javascript
Javascript获取数组中的最大值和最小值的方法汇总
2016/01/01 Javascript
jQuery弹层插件jquery.fancybox.js用法实例
2016/01/22 Javascript
浅析vue component 组件使用
2017/03/06 Javascript
js单页hash路由原理与应用实战详解
2017/08/14 Javascript
vue-cli中的webpack配置详解
2017/09/25 Javascript
vue 简单自动补全的输入框的示例
2018/03/12 Javascript
p5.js码绘“跳动的小正方形”的实现代码
2019/10/22 Javascript
详解jQuery中的prop()使用方法
2020/01/05 jQuery
vue-router定义元信息meta操作
2020/12/07 Vue.js
[49:05]OG vs Newbee 2019DOTA2国际邀请赛淘汰赛 胜者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
Python subprocess模块学习总结
2014/03/13 Python
Python操作json数据的一个简单例子
2014/04/17 Python
深入Python函数编程的一些特性
2015/04/13 Python
对python遍历文件夹中的所有jpg文件的实例详解
2018/12/08 Python
python可视化实现代码
2019/01/15 Python
Python程序打包工具py2exe和PyInstaller详解
2019/06/28 Python
html5跨域通讯之postMessage的用法总结
2013/11/07 HTML / CSS
同事打架检讨书
2014/02/04 职场文书
全国税务系统先进集体事迹材料
2014/05/19 职场文书
面试感谢信范文
2015/01/22 职场文书
2015年检验员工作总结范文
2015/04/30 职场文书
交通事故被告代理词
2015/05/23 职场文书
2015年学校精神文明工作总结
2015/05/27 职场文书
社区服务理念口号
2015/12/25 职场文书
学校趣味运动会开幕词
2016/03/04 职场文书
Linux系统下安装PHP7.3版本
2021/06/26 PHP
Python测试框架pytest高阶用法全面详解
2022/06/01 Python
Java结构型设计模式之组合模式详解
2022/09/23 Java/Android