Django中信号signals的简单使用方法


Posted in Python onJuly 04, 2019

正文

在平时的开发过程中,我们会遇到一些特殊的应用场景,如果你想要在执行某种操作之前或者之后你能够得到通知,并对其进行一些你想要的操作时,你就可以用Django中的信号(signals)。Django 提供一个“信号分发器”,允许解耦的应用在框架的其它地方发生操作时会被通知到,也就是说在特定事件发生时,可以发送一个信号去通知所有注册了这个信号的回调,在回调里进行想要的操作处理。

一.Django内置信号

Django内置了对数据表,migrate命令,url请求相关(request/response),使用test测试,连接数据库五大类信号。

Model signals
 pre_init   # model执行构造方法前,触发
 post_init   # model执行构造方法后,触发
 pre_save   # model执行save对象保存前,触发
 post_save   # model执行save对象保存前,触发
 pre_delete   # model执行delete对象删除前,触发
 post_delete   # model执行delete对象删除前,触发
 m2m_changed   # model使用多对多字段操作第三张表前后,触发
 class_prepared  # 程序启动时,检测已注册的model类,对每个类,触发

Management signals
 pre_migrate   # 执行migrate前,触发
 post_migrate   # 执行migrate后,触发

Request/response signals
 request_started  # 请求到来前,触发
 request_finished  # 请求结束后,触发
 got_request_exception # 请求异常后,触发

Test signals
 setting_changed  # 使用test测试修改配置文件,触发
 template_rendered  # 使用test测试渲染模板时,触发

Database Wrappers
 connection_created  # 创建数据库连接时,触发

1.常用内置信号参数介绍

(1)django.db.models.signals.pre_save

pre_save处理程序的参数介绍

参数名 参数介绍
sender 模型类
instance 保存的实际实例(保存后的model数据对象)
raw 布尔值; True如果模型完全按照提供的方式保存。不应该查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态
using 正在使用的数据库别名
update_fields 要传递给更新的字段集model.save(),或者None 如果update_fields未传递给它save()

(2)django.db.models.signals.post_save

post_save处理程序的参数介绍

参数名 参数介绍
sender 模型类
instance 保存的实际实例
created 布尔值; True如果创建了新记录(True表示数据创建)
raw 布尔值; True如果模型完全按照提供的方式保存。不应该查询/修改数据库中的其他记录,因为数据库可能尚未处于一致状态
using 正在使用的数据库别名
update_fields 要传递给更新的字段集model.save(),或者None 如果update_fields未传递给它save()

(3)django.db.models.signals.pre_delete

pre_delete处理程序的参数介绍

参数名 参数介绍
sender 模型类
instance 要删除的实际实例
using 正在使用的数据库别名

(4)django.db.models.signals.post_delete

post_delete处理程序的参数介绍

参数名 参数介绍
sender 模型类
instance 要删除的实际实例(该对象将不再存在于数据库中,因此请谨慎对待此实例)
using 正在使用的数据库别名

更多信号参数介绍请参考https://docs.djangoproject.com/zh-hans/2.1/ref/signals/

2.内置信号监听方法

对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数。当你写好一个接收器(receiver function)用于接收到信号以后的回调处理后,就需要将接收器连接到信号,有两种方法,手动连接,跟使用receiver装饰器的方式。

手动连接实现方法:

from django.db.models.signals import post_delete

def my_callback(sender, **kwargs):
 print(sender)
 print("信号已接收")

post_delete.connect(my_callback) # 信号连接接收器,用于收到信号的回调,如果想要指定某个表对象,直接指定sender

# connect参数接收
"""
receiver - 将连接到此信号的回调函数。回调函数名,不带括号
sender - 指定从中接收信号的特定发送方。
weak - Django默认将信号处理程序存储为弱引用。因此,如果您的接收器是本地功能,它可能被垃圾收集。为了防止这种情况,请weak=False在调用信号connect()方法时通过。
dispatch_uid - 在可能发送重复信号的情况下信号接收器的唯一标识符。
"""

receiver装饰器实现方法:

from django.dispatch import receiver
from django.db.models.signals import post_delete
from app.models import UCenter

@receiver(post_delete, sender=UCenter) # post_delete指定信号触发类型,sender指定到具体对象
def delete_u2user(sender, instance, **kwargs): # instance表示被删除的对象
 print(sender, instance)

更多信号操作相关问题参考文档https://docs.djangoproject.com/zh-hans/2.1/topics/signals/

二.自定义信号使用

 1.定义信号

from django.dispatch import Signal

test_signal = Signal(providing_args=["name", "age"]) # 声明一个test_signal的信号,提供给接收器name跟age两个参数(可自定义参数)

2.注册信号

def my_callback(sender, **kwargs):
 print(sender)
 print("信号已接收")

test_signal.connect(my_callback) # 注册信号,指定接收器为my_callback

3.触发信号

from xxx import test_signal

test_signal.send(sender='test', name='zzq', age='18') # 触发信号,发送name,age参数信息

当然这样在选择发送信号的方式有两种一种使用Signal.send,还有一种是Signal.send_robut。

send()与send_robust()处理接收器功能引起的异常的方式不同。

send()并不能捕获由接收器提出的任何异常; 它只是允许错误传播。因此,在面对错误时,不是所有接收器都可以被通知信号。

send_robust()捕获从Python Exception类派生的所有错误,并确保所有接收器都收到信号通知。如果发生错误,则会在引发错误的接收器的元组对中返回错误实例。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Python 相关文章推荐
Django学习笔记之Class-Based-View
Feb 15 Python
Python常用算法学习基础教程
Apr 13 Python
python远程连接服务器MySQL数据库
Jul 02 Python
python 实现数字字符串左侧补零的方法
Dec 04 Python
Python语言检测模块langid和langdetect的使用实例
Feb 19 Python
python Matplotlib底图中鼠标滑过显示隐藏内容的实例代码
Jul 31 Python
python实现身份证实名认证的方法实例
Nov 08 Python
python爬虫scrapy基本使用超详细教程
Feb 20 Python
python调试工具Birdseye的使用教程
May 25 Python
Python 中的 copy()和deepcopy()
Nov 07 Python
Python中的tkinter库简单案例详解
Jan 22 Python
Python集合set()使用的方法详解
Mar 18 Python
python3读取图片并灰度化图片的四种方法(OpenCV、PIL.Image、TensorFlow方法)总结
Jul 04 #Python
pybind11和numpy进行交互的方法
Jul 04 #Python
pandas计算最大连续间隔的方法
Jul 04 #Python
python SQLAlchemy 中的Engine详解
Jul 04 #Python
Python Pandas实现数据分组求平均值并填充nan的示例
Jul 04 #Python
pybind11在Windows下的使用教程
Jul 04 #Python
Pandas_cum累积计算和rolling滚动计算的用法详解
Jul 04 #Python
You might like
《OVERLORD》手游英文版即将上线 手机上也能扮演骨王
2020/04/09 日漫
Linux下PHP安装mcrypt扩展模块笔记
2014/09/10 PHP
Yii实现MySQL多数据库和读写分离实例分析
2014/12/03 PHP
PHP之将POST数据转化为字符串的实现代码
2016/11/03 PHP
jquery分页插件AmSetPager(自写)
2013/04/15 Javascript
表单类各种类型(文本框)失去焦点效果jquery代码
2013/04/26 Javascript
网页下载文件期间如何防止用户对网页进行其他操作
2014/06/27 Javascript
js判断一个字符串是否包含一个子串的方法
2015/01/26 Javascript
javascript HTML+CSS实现经典橙色导航菜单
2016/02/16 Javascript
JavaScript中transform实现数字翻页效果
2017/03/08 Javascript
详解Vue.js入门环境搭建
2017/03/17 Javascript
使用canvas实现一个vue弹幕组件功能
2018/11/30 Javascript
关于Vue源码vm.$watch()内部原理详解
2019/04/26 Javascript
[47:36]Optic vs Newbee 2018国际邀请赛小组赛BO2 第二场 8.17
2018/08/18 DOTA
python实现的一个p2p文件传输实例
2014/06/04 Python
VTK与Python实现机械臂三维模型可视化详解
2017/12/13 Python
python复制列表时[:]和[::]之间有什么区别
2018/10/16 Python
将pandas.dataframe的数据写入到文件中的方法
2018/12/07 Python
python频繁写入文件时提速的方法
2019/06/26 Python
用python实现英文字母和相应序数转换的方法
2019/09/18 Python
Python队列、进程间通信、线程案例
2019/10/25 Python
Python 生成一个从0到n个数字的列表4种方法小结
2019/11/28 Python
为什么说python适合写爬虫
2020/06/11 Python
Python faker生成器生成虚拟数据代码实例
2020/07/20 Python
Python 实现国产SM3加密算法的示例代码
2020/09/21 Python
使用sublime text3搭建Python编辑环境的实现
2021/01/12 Python
Molton Brown美国官网:奢华美容、香水、沐浴和身体护理
2020/09/02 全球购物
摩飞电器俄罗斯官方网站:Morphy Richards俄罗斯
2020/07/30 全球购物
函授毕业生自我鉴定范文
2014/03/25 职场文书
竞聘上岗演讲
2014/05/19 职场文书
全运会口号
2014/06/20 职场文书
2016党员读书思廉心得体会
2016/01/23 职场文书
python 利用PyAutoGUI快速构建自动化操作脚本
2021/05/31 Python
关于CSS浮动与取消浮动的问题
2021/06/28 HTML / CSS
关于Redis的主从复制及哨兵问题
2022/06/16 Redis
java实现自定义时钟并实现走时功能
2022/06/21 Java/Android