Django的信号机制详解


Posted in Python onMay 05, 2017

Django提供一种信号机制。其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) 。当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行。

Django内置了一些信号,比如:

django.db.models.signals.pre_save 在某个Model保存之前调用
django.db.models.signals.post_save 在某个Model保存之后调用
django.db.models.signals.pre_delete 在某个Model删除之前调用
django.db.models.signals.post_delete 在某个Model删除之后调用
django.core.signals.request_started 在建立Http请求时发送
django.core.signals.request_finished 在关闭Http请求时发送

我们要做的,就是注册一个receiver函数。例如,如果要在每次请求完成之后,打印一行字。

可以使用回调的方式注册:

# receiver
def my_callback(sender, **kwargs):
  print("Request finished!")
 
# connect
from django.core.signalsimport request_finished
 
request_finished.connect(my_callback)

也可以使用装饰器的方式注册,下面这段代码和上面完全是等价的。

from django.core.signalsimport request_finished
from django.dispatchimport receiver
 
@receiver(request_finished)
def my_callback(sender, **kwargs):
  print("Request finished!")

receiver回调函数除了可以使用sender之外,还可以使用其他一些参数,比如针对pre_save函数:

sender:发送者(如果是pre_save的话,就是model class)
instance:实例
raw
using
update_fields
post_save()是一个比较实用函数,可以支持一些联动的更新。而不必让我们每次都写在view里面。比如:有用户提交了退款申请,我们需要把订单的状态修改成“已退款”的状态。就可以使用信号机制,而不必在每处都修改。

@receiver(post_save, sender=RefundForm)
deforder_state_update(sender, instance, created, **kwargs):
  instance.order.state = REFUNDING
  instance.order.save() # 这里,order是refundform的一个外键

当然,这里可以写的更多更周全,例如退款单取消改回状态等。

观察者是非常实用的一个设计模式,Django也支持用户 自定义 一些信号。

Python 相关文章推荐
Python常见加密模块用法分析【MD5,sha,crypt模块】
May 24 Python
python 调用win32pai 操作cmd的方法
May 28 Python
详解python之多进程和进程池(Processing库)
Jun 09 Python
python调用Matplotlib绘制分布点并且添加标签
May 31 Python
python3基于TCP实现CS架构文件传输
Jul 28 Python
对python中词典的values值的修改或新增KEY详解
Jan 20 Python
python实现五子棋游戏
Jun 18 Python
wxPython之wx.DC绘制形状
Nov 19 Python
解决Tensorflow sess.run导致的内存溢出问题
Feb 05 Python
Python多进程编程常用方法解析
Mar 26 Python
django日志默认打印request请求信息的方法示例
May 17 Python
详解python内置模块urllib
Sep 09 Python
Python中模块与包有相同名字的处理方法
May 05 #Python
详解python 字符串和日期之间转换 StringAndDate
May 04 #Python
Pycharm学习教程(7)虚拟机VM的配置教程
May 04 #Python
python 统计代码行数简单实例
May 04 #Python
利用PyInstaller将python程序.py转为.exe的方法详解
May 03 #Python
Pycharm学习教程(6) Pycharm作为Vim编辑器使用
May 03 #Python
利用numpy+matplotlib绘图的基本操作教程
May 03 #Python
You might like
基于数据库的在线人数,日访问量等统计
2006/10/09 PHP
php数组函数序列之array_combine() - 数组合并函数使用说明
2011/10/29 PHP
thinkphp 一个页面使用2次分页的实现方法
2013/07/15 PHP
PHP获取浏览器信息类和客户端地理位置的2个方法
2014/04/24 PHP
PHP中round()函数对浮点数进行四舍五入的方法
2014/11/19 PHP
php操作redis缓存方法分享
2015/06/03 PHP
PHP中Session ID的实现原理实例分析
2019/08/17 PHP
PHP autoload使用方法及步骤详解
2020/09/05 PHP
根据出生日期自动取得星座的js代码
2010/07/20 Javascript
Raphael一个用于在网页中绘制矢量图形的Javascript库
2013/01/08 Javascript
解读JavaScript中 For, While与递归的用法
2013/05/07 Javascript
Javascript实现的常用算法(如冒泡、快速、鸽巢、奇偶等)
2014/04/29 Javascript
Js可拖拽放大的层拖动特效实现方法
2015/02/25 Javascript
jQuery DOM删除节点操作指南
2015/03/03 Javascript
jQuery+slidereveal实现的面板滑动侧边展出效果
2015/03/14 Javascript
javascript事件冒泡和事件捕获详解
2015/05/26 Javascript
JavaScript实现快速排序的方法
2015/07/31 Javascript
js基于setTimeout与setInterval实现多线程
2016/06/17 Javascript
BootStrap学习笔记之nav导航栏和面包屑导航
2017/01/03 Javascript
jquery获取transform里的值实现方法
2017/12/12 jQuery
js如何找出字符串中的最长回文串
2018/06/04 Javascript
微信{"errcode":48001,"errmsg":"api unauthorized, hints: [ req_id: 1QoCla0699ns81 ]"}
2018/10/12 Javascript
python中List的sort方法指南
2014/09/01 Python
Python正则表达式常用函数总结
2017/06/24 Python
Python中工作日类库Busines Holiday的介绍与使用
2017/07/06 Python
Python基于回溯法子集树模板解决马踏棋盘问题示例
2017/09/11 Python
python Spyder界面无法打开的解决方法
2018/04/27 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
Python 列表去重去除空字符的例子
2019/07/20 Python
Python 网络编程之UDP发送接收数据功能示例【基于socket套接字】
2019/10/11 Python
实习自我鉴定范文
2013/10/30 职场文书
2014年健康教育实施方案
2014/02/17 职场文书
护士自我鉴定总结
2014/03/24 职场文书
消防验收申请报告
2015/05/15 职场文书
医院病假条怎么写
2015/08/17 职场文书
大学生饮品店创业计划书范文
2019/07/10 职场文书