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处理python编码问题
Mar 13 Python
Python使用urllib模块的urlopen超时问题解决方法
Nov 08 Python
简单实现python爬虫功能
Dec 31 Python
Python的Flask框架中集成CKeditor富文本编辑器的教程
Jun 13 Python
浅析python中SQLAlchemy排序的一个坑
Feb 24 Python
老生常谈进程线程协程那些事儿
Jul 24 Python
python XlsxWriter模块创建aexcel表格的实例讲解
May 03 Python
用于业余项目的8个优秀Python库
Sep 21 Python
Python中xml和json格式相互转换操作示例
Dec 05 Python
Python Selenium 之关闭窗口close与quit的方法
Feb 13 Python
基于python实现对文件进行切分行
Apr 26 Python
scrapy结合selenium解析动态页面的实现
Sep 28 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递归实现无限分类 格式化数组的详解
2013/06/08 PHP
php生成xml时添加CDATA标签的方法
2014/10/17 PHP
php+mysql删除指定编号员工信息的方法
2015/01/14 PHP
PHP进程同步代码实例
2015/02/12 PHP
PHP编程中的__clone()方法使用详解
2015/11/27 PHP
基于PHP+mysql实现新闻发布系统的开发
2020/08/06 PHP
JavaScript之HTMLCollection接口代码
2011/04/27 Javascript
基于jquery的代码显示区域自动拉长效果
2011/12/07 Javascript
jquery延迟加载外部js实现代码
2013/01/11 Javascript
基于jQuery实现模拟页面加载进度条
2013/04/01 Javascript
jquery用get实现ajax在ie里面刷新不进入后台解决方法
2013/08/12 Javascript
javascript实现的固定位置悬浮窗口实例
2015/04/30 Javascript
推荐阅读的js快速判断IE浏览器(兼容IE10与IE11)
2015/12/13 Javascript
bootstrap datepicker插件默认英文修改为中文
2017/07/28 Javascript
vue 解决addRoutes动态添加路由后刷新失效问题
2018/07/02 Javascript
浅谈微信页面入口文件被缓存解决方案
2018/09/29 Javascript
layui 表单标签的校验方法
2019/09/04 Javascript
[02:51]DOTA2战队出征照拍摄花絮 TI3明星化身时尚男模
2013/07/22 DOTA
详解python使用递归、尾递归、循环三种方式实现斐波那契数列
2018/01/16 Python
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
django 解决manage.py migrate无效的问题
2018/05/27 Python
Django项目开发中cookies和session的常用操作分析
2018/07/03 Python
python http基本验证方法
2018/12/26 Python
用uWSGI和Nginx部署Flask项目的方法示例
2019/05/05 Python
Python增强赋值和共享引用注意事项小结
2019/05/28 Python
Django的models中on_delete参数详解
2019/07/16 Python
纯CSS实现预加载动画效果
2017/09/06 HTML / CSS
CSS图片翻转动画技术详解(IE也实现了)
2014/04/03 HTML / CSS
如何在网站上添加谷歌定位信息
2016/04/16 HTML / CSS
毕业生的求职信范文分享
2013/12/04 职场文书
学生会主席事迹材料
2014/01/28 职场文书
初中学生评语大全
2014/04/24 职场文书
党员自我剖析材料(群众路线)
2014/10/06 职场文书
看雷锋电影观后感
2015/06/10 职场文书
同学聚会开幕词
2019/04/02 职场文书
JavaScript 去重和重复次数统计
2021/03/31 Javascript