利用信号如何监控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基础教程之类class定义使用方法
Feb 20 Python
python有证书的加密解密实现方法
Nov 19 Python
python中函数传参详解
Jul 03 Python
python看某个模块的版本方法
Oct 16 Python
使用CodeMirror实现Python3在线编辑器的示例代码
Jan 14 Python
python实践项目之监控当前联网状态详情
May 23 Python
关于PyTorch 自动求导机制详解
Aug 18 Python
详解python播放音频的三种方法
Sep 23 Python
python GUI库图形界面开发之PyQt5 Qt Designer工具(Qt设计师)详细使用方法及Designer ui文件转py文件方法
Feb 26 Python
opencv 查找连通区域 最大面积实例
Jun 04 Python
详解python 支持向量机(SVM)算法
Sep 18 Python
10个顶级Python实用库推荐
Mar 04 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面试题 试试看看你会不会也中招
2014/08/19 PHP
PHP中余数、取余的妙用
2015/06/29 PHP
php session的锁和并发
2016/01/22 PHP
PHP缓冲区用法总结
2016/02/14 PHP
PHP中的use关键字及文件的加载详解
2016/11/28 PHP
php实现文件管理与基础功能操作
2017/03/21 PHP
老生常谈PHP中的数据结构:DS扩展
2017/07/17 PHP
PHP7如何开启Opcode打造强悍性能详解
2018/05/11 PHP
JavaScript脚本性能优化注意事项
2008/11/18 Javascript
javascript this用法小结
2008/12/19 Javascript
jQuery点击弹出下拉菜单的小例子
2013/08/01 Javascript
jQuery找出网页上最高元素的方法
2015/03/20 Javascript
JS延时提示框实现方法详解
2015/11/26 Javascript
node+express制作爬虫教程
2016/11/11 Javascript
vue2.0 与 bootstrap datetimepicker的结合使用实例
2017/05/22 Javascript
详解express与koa中间件模式对比
2017/08/07 Javascript
vue组件watch属性实例讲解
2017/11/07 Javascript
JS实现简易留言板增删功能
2020/02/08 Javascript
vue中音频wavesurfer.js的使用方法
2020/02/20 Vue.js
[31:29]完美世界DOTA2联赛PWL S3 INK ICE vs Magma 第一场 12.20
2020/12/23 DOTA
TensorFlow实现Batch Normalization
2018/03/08 Python
python求解数组中两个字符串的最小距离
2018/09/27 Python
对dataframe数据之间求补集的实例详解
2019/01/30 Python
python3实现字符串操作的实例代码
2019/04/16 Python
Python爬取知乎图片代码实现解析
2019/09/17 Python
Python 识别12306图片验证码物品的实现示例
2020/01/20 Python
前端制作动画的几种方式(css3,js)
2016/12/12 HTML / CSS
css3+jq创作含苞待放的荷花
2014/02/20 HTML / CSS
工程项目经理岗位职责
2013/12/15 职场文书
30年同学聚会邀请函
2014/01/25 职场文书
消防安全宣传标语
2014/06/07 职场文书
中职毕业生自我鉴定
2014/09/13 职场文书
财务工作个人总结
2015/02/27 职场文书
给老婆的检讨书(搞笑版)
2015/05/06 职场文书
手写实现JS中的new
2021/11/07 Javascript
68行Python代码实现带难度升级的贪吃蛇
2022/01/18 Python