我的编程空间,编程开发者的网络收藏夹
学习永远不晚

深入理解Django的信号机制

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

深入理解Django的信号机制

Django的信号

Django的信号机制不同于Linux的信号机制,Django 中的信号用于在框架执行操作时解耦。当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作

Django的信号主要包含以下三个要素:

  • 发送者(sender):信号的发出方。
  • 信号(signal):发送的信号本身。
  • 接收者(receiver):信号的接收者。

其中接受者就是回调函数,会把这个函数注册到信号之上。当特定事件发生之后,发送者发送信号,然后执行回调函数。

Django信号的使用

查看Django Signal的源码,看到Django的信号存在以下方法

image-20230202162549086

除了上面的几个方法,还有几个属性

  • lock
  • recievers
  • sender_receivers_cache
  • use_caching

根据第一趴介绍知道,要使用Django的信号,需要满足三要素(发送者、接受者、和信号)

Django通过connect() 函数监听 信号,接受发送者发送的信号,然后执行接受者(回调函数)

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

其中

  • recievers 是接受者,本质就是一个回调函数
  • sender 是发送信号的主体,如果connect连接的时候,sender 是None(默认也是None)代表该信号接受所有发送者发送的该信号;否则只接受具体的发送者(一个Python对象,比如Django的 Model对象)
  • weak – Django 默认将信号处理程序存储为弱引用。因此,如果你的接收器是本地函数,则可能会对其进行垃圾回收。要防止这种情况发生,当你要调用 connect() 方法时请传入 weak=False。
  • dispatch_uid 在可能发送重复信号的情况下,信号接收器的唯一标识符。

具体使用方式

1、需要定义一个回调函数

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

2、把回调函数 注册到对应的信号

from django.core.signals import request_finished
request_finished.connect(my_callback)

注意这里没有指定sender,那么就是接受任意发送者哦

或者更简单的方式是使用 receiver 函数

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

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

或者指定具体的发送者

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

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

==> 划重点

一般我们会把 回调函数信号注册 放到一个应用的目录下的 signals.py 文件中去

然后在该应用的 apps.py 中应用

from django.apps import AppConfig
from django.core.signals import request_finished

class MyAppConfig(AppConfig):
    ...

    def ready(self):
        # Implicitly connect signal handlers decorated with @receiver.
        from . import signals
        # Explicitly connect a signal handler.
        request_finished.connect(signals.my_callback)

这样只要改应用安装在 INSTALLED_APPS 中去,那么Django就能识别到具体的信号(包括自定义的信号)以及进行信号的处理(因为已经自动通过 connect进行监听 )

为啥会自动监听呢,当然是 Django的 AppConfig 下的 ready() 函数的作用

自定义信号

首先有个核心点需要明确

所有的信号都是 django.dispatch.Signal 的实例。

比如这里新增一个发送邮件的信号,每次新增Post之后,发送邮件给相关订阅的人

# demoapp/signals.py
from django.db.models.signals import post_save
from django.dispatch import receiver

from .models import Post

@receiver(post_save, sender=Post)
def send_mail(sender, instance, created, **kwargs):
	if created:
		print(f"current instance {instance}")
		print("Try to send mail to subscriber")

然后把信号导入到 appConfig 的ready() 函数中去

# demoapp/apps.py

from django.apps import AppConfig


class DemoappConfig(AppConfig):
    default_auto_field = 'django.db.models.BigAutoField'
    name = 'demoapp'

    def ready(self):
        import demoapp.signals

然后我们在admin注册Post之后,新增Post,在命令行日志中就能看到

current instance DemoPost First One
Try to send mail to subscriber
[02/Feb/2023 13:47:29] "POST /admin/demoapp/post/add/ HTTP/1.1" 302 0

还有另外一个 主动发送信号的方式

1、先定义回调函数 callback_func

2、定义一个信号 mail_send_signal = Signal()

3、回调函数注册到信号 mail_send_signal.connect(callback_func)

3、主动发送信号 mail_send_signal.send(sender=xxx, **kwargs)

具体的代码实现,可以手动尝试哦,实践出真知嘛~

扩展:查看Django信号的接受者

Django内置信号的reciever查看

(kfzops) [ 23-02-02 16:04 ] [ colinspace.com ] python manage.py shell
Python 3.9.6 (default, Jul 16 2021, 13:41:17)
[Clang 12.0.5 (clang-1205.0.22.11)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> from django.db.models.signals import post_migrate
>>> post_migrate.receivers
[(('django.contrib.auth.management.create_permissions', 4304618416), <weakref at 0x10232b310; to 'function' at 0x10231d1f0 (create_permissions)>), ((4331786592, 4304618416), <weakref at 0x102581e00; to 'function' at 0x10231d160 (create_contenttypes)>)]

扩展:Django内置信号

Django内置了很多有用的信号,大概有以下几类,可以作为了解。

模型相关的信号

  • pre_init
  • post_init
  • pre_save
  • post_save
  • pre_delete
  • post_delete
  • m2m_changed
  • class_prepared

其中

1、pre_init/post_init 分别会在模型的__init__() 方法调用 之前/之后发出

2、pre_save/post_save 分别会在模型的save() 方法调用 之前/之后发出

3、pre_delete/post_delete 分别会在模型的delete() 方法调用 之前/之后发出

4、m2m_changed 严格意义上来说是由ManyToManyField 字段发生变化的时候发出的

5、class_prepared 比较特殊一般不建议用

django-admin 发出的信号,确切的说是 Django admin在执行 python manage.py migrate的时候发出的信号

  • pre_migrete
  • post_migrate

顾名思义,不做过多解释

请求响应信号,也就是Django 发起request和响应response的信号

  • request_started
  • request_finished
  • get_request_exception

另外还有几个特殊的信号

1、setting_changed 只有当运行测试用例的时候发出

2、template_render 当测试系统渲染模板的时候发出

3、connect_created 当数据库连接启动的时候,数据库管理器发出

参考文档

1、 https://docs.djangoproject.com/zh-hans/4.1/topics/signals/

到此这篇关于深入理解Django的信号机制的文章就介绍到这了,更多相关Django 信号机制内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

深入理解Django的信号机制

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

深入理解Django的信号机制

本文主要介绍了深入理解Django的信号机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
2023-02-08

Django的信号机制详解

Django提供一种信号机制。其实就是观察者模式,又叫发布-订阅(Publish/Subscribe) 。当发生一些动作的时候,发出信号,然后监听了这个信号的函数就会执行。 Django内置了一些信号,比如:django.db.models
2022-06-04

深入理解Android中的Handler异步通信机制

一、问题:在Android启动后会在新进程里创建一个主线程,也叫UI线程(非线程安全)这个线程主要负责监听屏幕点击事件与界面绘制。当Application需要进行耗时操作如网络请求等,如直接在主线程进行容易发生ANR错误。所以会创建子线程来
2022-06-06

linux信号解释(3)--信号处理机制

如果需要进程捕获某个信号,并作出相应的处理,就需要注册信号处理函数(其实就是内核里需要识别信号函数,类似C语言里的include某函数库)。    处理信号就类似软中断,内核为每个进程准备了一段信号向量表,记录信号的处理机制。当某个信号发生
2023-01-31

深入理解spring的AOP机制原理

前言在软件开发中,散布于应用中多处的功能被称为横切关注点,通常来讲,这些横切关注点从概念上是与应用的业务逻辑相分离的。把这些横切关注点和业务逻辑分离出来正是AOP要解决的问题。AOP能够帮我们模块化横切关注点,换言之,横切关注点可以被描述为
2023-05-31

Android 渲染机制深入理解

基础知识 CPU: 中央处理器,它集成了运算,缓冲,控制等单元,包括绘图功能.CPU将对象处理为多维图形,纹理(Bitmaps、Drawables等都是一起打包到统一的纹理)。 GPU:一个类似于CPU的专门用来处理Graphics的处理器
2022-06-06

Java反射机制深入理解

Java反射机制深入理解一.概念   反射就是把Java的各种成分映射成相应的Java类。Class类的构造方法是private,由JVM创建。反射是java语言的一个特性,它允程序在运行时(注意不是编译的时候)来进行自我检查并且对内部的成
2023-05-31

深入理解JavaScript事件机制

事件机制是几乎所有开发语言都有的机制,并不是deviceone的独创,在某些语言称之为消息(Event),有些地方称之为(Message).接下来通过本文给大家介绍JS事件机制的理解,需要的朋友一起学习吧
2023-05-17

深入理解SQL COUNT的内部机制

在理解SQL COUNT的内部机制之前,首先需要了解COUNT是一个聚合函数,用于统计查询结果中的行数。它可以用来统计表中特定列的非NULL值的数量,或者统计表中的所有行数。COUNT函数的用法通常如下所示:SELECT COUNT(c
深入理解SQL COUNT的内部机制
2024-08-10

深入理解异步事件机制

通过了解异步设计的由来,来深入理解异步事件机制。代码地址什么是异步同步并发(Concurrency)线程(Thread)I/O多路复用异步(Asynchronous)回调(Callback)参考文献为了深入理解异步的概念,就必须先了解异步设
2023-01-31

深入理解PHP中的值传递机制

深入理解PHP中的值传递机制PHP是一种流行的服务器端脚本语言,广泛应用于Web开发领域。在PHP中,有两种传递参数的方式:值传递(pass by value)和引用传递(pass by reference)。本文将重点探讨PHP中的值传
深入理解PHP中的值传递机制
2024-03-08

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录