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获取一组数据里最大值max函数用法实例
May 26 Python
Python中的推导式使用详解
Jun 03 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
python中的插值 scipy-interp的实现代码
Jul 23 Python
详解pandas使用drop_duplicates去除DataFrame重复项参数
Aug 01 Python
对python中的*args与**kwgs的含义与作用详解
Aug 28 Python
大家都说好用的Python命令行库click的使用
Nov 07 Python
python求一个字符串的所有排列的实现方法
Feb 04 Python
python分别打包出32位和64位应用程序
Feb 18 Python
使用Python webdriver图书馆抢座自动预约的正确方法
Mar 04 Python
python 爬取天气网卫星图片
Jun 07 Python
Python下opencv库的安装过程及问题汇总
Jun 11 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
PHP中使用crypt()实现用户身份验证的代码
2012/09/05 PHP
基于php上传图片重命名的6种解决方法的详细介绍
2013/04/28 PHP
zend framework文件上传功能实例代码
2013/12/25 PHP
PHP的引用详解
2015/02/22 PHP
JS+PHP实现用户输入数字后显示最大的值及所在位置
2017/06/19 PHP
转换json格式的日期为Javascript对象的函数
2010/07/13 Javascript
jquery-easyui关闭tab自动切换到前一个tab
2010/07/29 Javascript
JavaScript 一道字符串分解的题目
2011/08/03 Javascript
理清apply(),call()的区别和关系
2011/08/14 Javascript
jquery简单的拖动效果实现原理及示例
2013/07/26 Javascript
js实现跨域的方法实例详解
2015/06/24 Javascript
莱鸟介绍javascript onclick事件
2016/01/06 Javascript
Bootstrap+jfinal退出系统弹出确认框的实现方法
2016/05/30 Javascript
Bootstrap布局组件教程之Bootstrap下拉菜单
2016/06/12 Javascript
js实现键盘自动打字效果
2016/12/23 Javascript
angular2实现统一的http请求头方法
2018/08/13 Javascript
vue实现防抖的实例代码
2021/01/11 Vue.js
[00:52]玛尔斯技能全介绍
2019/03/06 DOTA
[00:16]热血竞技场
2019/03/06 DOTA
[54:19]完美世界DOTA2联赛PWL S2 Magma vs PXG 第二场 11.28
2020/12/01 DOTA
[01:06:54]DOTA2-DPC中国联赛 正赛 RNG vs Dragon BO3 第一场 1月24日
2021/03/11 DOTA
python发送邮件示例(支持中文邮件标题)
2014/02/16 Python
Python实现端口复用实例代码
2014/07/03 Python
python 禁止函数修改列表的实现方法
2017/08/03 Python
python opencv人脸检测提取及保存方法
2018/08/03 Python
Python PyAutoGUI模块控制鼠标和键盘实现自动化任务详解
2018/09/04 Python
详解通过HTML5 Canvas实现图片的平移及旋转变化的方法
2016/03/22 HTML / CSS
详解如何通过H5(浏览器/WebView/其他)唤起本地app
2017/12/11 HTML / CSS
h5页面背景图很长要有滚动条滑动效果的实现
2021/01/27 HTML / CSS
香港个人化生活购物网站:Ballyhoo Limited
2016/09/10 全球购物
Hotels.com台湾:饭店订房网
2017/09/06 全球购物
.NET面试问题集
2015/12/08 面试题
公开服务承诺制度
2014/03/26 职场文书
物理学专业求职信
2014/07/04 职场文书
闪闪红星观后感
2015/06/08 职场文书
JS不要再到处使用绝对等于运算符了
2021/04/30 Javascript