3分钟看懂Python后端必须知道的Django的信号机制

作者:画星星高手 时间:2022-08-17 18:17:55 

概念

django自带一套信号机制来帮助我们在框架的不同位置之间传递信息。也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者(receivers)。

(感觉就很像Qt的信号与槽机制)

信号系统包含以下三要素:

  • 发送者-信号的发出方

  • 信号-信号本身

  • 接收者-信号的接受者

Django内置了一整套信号,下面是一些比较常用的:

Django内置信号


Model signals
 pre_init          # django的modal执行其构造方法前,自动触发
 post_init          # django的modal执行其构造方法后,自动触发
 pre_save          # django的modal对象保存前,自动触发
 post_save          # django的modal对象保存后,自动触发
 pre_delete         # django的modal对象删除前,自动触发
 post_delete         # django的modal对象删除后,自动触发
 m2m_changed         # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
 class_prepared       # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
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     # 创建数据库连接时,自动触发

在ORM模型的save()方法调用之前或之后发送信号


django.db.models.signals.pre_save
django.db.models.signals.post_save

在ORM模型或查询集的delete()方法调用之前或之后发送信号。


django.db.models.signals.pre_delete
django.db.models.signals.post_delete

当多对多字段被修改时发送信号。


django.db.models.signals.m2m_changed

当接收和关闭HTTP请求时发送信号。


django.core.signals.request_started
django.core.signals.request_finished

这就很方便了,想象一下这样一个情景,我们引入了一个第三方的Django库,他会创建模型,我们想要在不修改他的代码的情况下,在他创建模型的时候同时修改其他表的数据,那么这时候信号机制就能派上用场了。

简单使用例子
信号监听有两种方式,一种是 Signal.connect() 方法,一种是装饰器。

Signal.connect()方法

方法原型:


Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)[source]

参数:

  • receiver :当前信号连接的回调函数,也就是处理信号的函数。

  • sender :指定从哪个发送方接收信号。

  • weak : 是否弱引用

  • dispatch_uid :信号 * 的唯一标识符,以防信号多次发送。

装饰器法


from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
 print("Request finished!")

可以给 receiver 添加 sender 参数来筛选接收哪个模型产生的信号,比如:


from django.db.models import signals
from django.dispatch import receiver

@receiver(signals.post_save, sender=MyModel)
def demo_callback(sender: MyModel, instance: MyModel, **kwargs):
 pass

注意要读取传入的模型对象一定是要用 instance 参数,不是 sender ! sender 是一个类型!

设置dispatch_uid参数防止重复信号
为了防止重复信号,可以设置dispatch_uid参数来标识你的 * ,标识符通常是一个字符串,如下所示:


from django.core.signals import request_finished

request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")

断开信号

在满足某些条件下,我们不再需要监听信号,可以选择断开信号。

Signal.disconnect()用来断开信号的 * 。和Signal.connect()中的参数相同。如果 * 成功断开,返回True,否则返回False。


Signal.disconnect(receiver=None, sender=None, dispatch_uid=None)[source]

后记

最近刚入职项目很多特别的忙,也学到了很多新技术,但是感觉已经好久没有时间来好好写一篇博客了,就算是本文也是短时间拼凑的,真是难呀,周末得好好整理一下最近的技术笔记。

关于Django信号机制的更多内容(自定义信号等),可以参考官方文档。 https://docs.djangoproject.com/en/3.0/topics/signals/

来源:https://www.cnblogs.com/deali/p/13372922.html

标签:Django,信号机制
0
投稿

猜你喜欢

  • python3+django2开发一个简单的人员管理系统过程详解

    2022-06-01 08:04:01
  • Django前后端分离csrf token获取方式

    2021-03-15 04:23:43
  • Python学习pygal绘制线图代码分享

    2022-12-02 10:51:48
  • 常用ASP自定义函数集 (S.Sams)

    2010-05-27 12:24:00
  • Sklearn调优之网格搜索与随机搜索原理详细分析

    2022-05-11 10:47:12
  • 运用python去除图片水印

    2021-05-06 10:54:20
  • Python selenium 三种等待方式详解(必会)

    2021-03-13 16:03:33
  • Python之is与==的区别详解

    2021-08-23 21:00:04
  • Python中的多行注释文档编写风格汇总

    2023-05-05 02:41:18
  • Access 2003开发者扩展工具集概述

    2009-03-19 18:32:00
  • AlternatingItemTemplate类似于 ItemTemplate 元素

    2023-07-14 13:09:07
  • 如何调用Oracle存储过程?

    2009-11-15 20:13:00
  • mysql5.7.20第一次登录失败的快速解决方法

    2024-01-19 16:57:36
  • Python lambda表达式原理及用法解析

    2021-03-02 18:52:12
  • python高效过滤出文件夹下指定文件名结尾的文件实例

    2023-08-03 13:55:13
  • python中文件操作与异常的处理图文详解

    2021-09-04 16:04:33
  • python互斥锁、加锁、同步机制、异步通信知识总结

    2023-10-08 21:17:16
  • NopCommerce架构分析(一)Autofac依赖注入类生成容器

    2023-07-11 21:20:27
  • python算法与数据结构之单链表的实现代码

    2022-09-30 14:35:39
  • 将Python中的数据存储到系统本地的简单方法

    2021-08-22 18:15:55
  • asp之家 网络编程 m.aspxhome.com