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使用scrapy采集数据时为每个请求随机分配user-agent的方法
Apr 08 Python
在CentOS上配置Nginx+Gunicorn+Python+Flask环境的教程
Jun 07 Python
Python中 Lambda表达式全面解析
Nov 28 Python
使用python遍历指定城市的一周气温
Mar 31 Python
Python遍历某目录下的所有文件夹与文件路径
Mar 15 Python
Python3 使用pillow库生成随机验证码
Aug 26 Python
wxPython实现文本框基础组件
Nov 18 Python
如何通过python实现全排列
Feb 11 Python
Python数据结构dict常用操作代码实例
Mar 12 Python
解决jupyter notebook import error但是命令提示符import正常的问题
Apr 15 Python
基于Python把网站域名解析成ip地址
May 25 Python
Python selenium的这三种等待方式一定要会!
Jun 10 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脚本的10个技巧(5)
2006/10/09 PHP
学习JS面向对象成果 借国庆发布个最新作品与大家交流
2009/10/03 Javascript
基于JQuery的Select选择框的华丽变身
2011/08/23 Javascript
JavaScript高级程序设计 学习笔记 js高级技巧
2011/09/20 Javascript
『jQuery』取指定url格式及分割函数应用
2013/04/22 Javascript
JavaScript实现表格排序方法
2013/06/14 Javascript
JSP跨iframe如何传递参数实现代码
2013/09/21 Javascript
JavaScript中的原始值和复杂值
2016/01/07 Javascript
JS实现点击登录弹出窗口同时背景色渐变动画效果
2016/03/25 Javascript
jQuery实现微信长按识别二维码功能
2016/08/26 Javascript
Vue完整项目构建(进阶篇)
2018/02/10 Javascript
JS/HTML5游戏常用算法之碰撞检测 包围盒检测算法详解【矩形情况】
2018/12/13 Javascript
koa2+vue实现登陆及登录状态判断
2019/08/15 Javascript
js实现适配移动端的拖动效果
2020/01/13 Javascript
vuex 多模块时 模块内部的mutation和action的调用方式
2020/07/24 Javascript
详解webpack的clean-webpack-plugin插件报错
2020/10/16 Javascript
vue3.0中setup使用(两种用法)
2020/12/02 Vue.js
[44:51]2018DOTA2亚洲邀请赛 4.4 淘汰赛 VP vs Liquid 第二场
2018/04/05 DOTA
Python中用Spark模块的使用教程
2015/04/13 Python
python开发之字符串string操作方法实例详解
2015/11/12 Python
Python实现PS滤镜碎片特效功能示例
2018/01/24 Python
Python使用Pickle库实现读写序列操作示例
2018/06/15 Python
通过python实现随机交换礼物程序详解
2019/07/10 Python
python中property属性的介绍及其应用详解
2019/08/29 Python
Python实现RGB与HSI颜色空间的互换方式
2019/11/27 Python
Pytorch之view及view_as使用详解
2019/12/31 Python
Pytorch在dataloader类中设置shuffle的随机数种子方式
2020/01/14 Python
经验丰富程序员才知道的8种高级Python技巧
2020/07/27 Python
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
安全生产网格化管理实施方案
2014/03/01 职场文书
党员领导干部民主生活会批评与自我批评发言
2014/09/28 职场文书
看上去很美观后感
2015/06/10 职场文书
安全生产感想
2015/08/07 职场文书
Windows11性能真的上涨35%? 桌面酷睿i9实测结果公开
2021/11/21 数码科技
ORACLE中dbms_output.put_line输出问题的解决过程
2022/06/28 Oracle
Apache SkyWalking 监控 MySQL Server 实战解析
2022/09/23 Servers