Django信号详解

Django信号(Signals)是一种允许应用组件在特定事件发生时进行通信的机制,而不必直接引用彼此。它遵循观察者模式,允许发送者(如模型实例的保存或删除)发送信号,而接收者(信号处理器)可以监听这些信号并作出响应,从而实现松耦合的组件间通信。

Django内置信号

模型(Model)相关的信号

  • pre_init:在Django模型实例化其构造方法之前触发。
  • post_init:在Django模型实例化其构造方法之后触发。
  • pre_save:在Django模型对象保存到数据库之前触发。
  • post_save:在Django模型对象保存到数据库之后触发,无论对象是新建还是更新。
  • pre_delete:在Django模型对象从数据库中删除之前触发。
  • post_delete:在Django模型对象从数据库中删除之后触发。
  • m2m_changed:在使用Many-to-Many字段进行添加、移除或清空操作前后触发。
  • class_prepared:当Django发现并准备使用已注册应用中的模型类时触发。

数据库迁移相关的信号

  • pre_migrate:执行migrate命令前触发。
  • post_migrate:执行migrate命令后触发。

请求和响应相关的信号

  • request_started 和 request_finished:分别在Django开始处理HTTP请求和完成请求处理后触发。
  • got_request_exception:当视图函数中抛出异常时触发。

测试相关的信号

  • Test signals:在测试运行的不同阶段触发,用于测试环境的设置或清理等。

其他信号

  • setting_changed:当Django设置在运行时被更改时触发。
  • template_rendered:模板渲染完成后触发,可用于模板调试。

使用场景

  1. 日志记录:在模型保存或删除时自动记录日志。
  2. 通知系统:用户操作后发送邮件或短信通知。
  3. 权限检查:在模型保存前检查用户是否有相应权限。
  4. 数据同步:数据库更改后同步到搜索引擎或缓存系统。
  5. 清理任务:删除模型实例时,同步清理关联的文件或资源。
  6. 异步处理:在视图操作后触发异步任务,如发送邮件、处理图像等。

使用示例

假设我们有一个如下User模型,我们希望每次有User对象新创建时都打印出有新用户注册的提示信息,我们可以使用Django信号(signals)轻松实现。我们的信号发送者sender是User模型,每当User模型执行post_save动作时就会发出信号。此时我们自定义的create_user函数一旦监听到User发出的post_save信号就会执行,先通过if created判断对象是新创建的还是被更新的;如果对象是新创建的,就会打印出提示信息。

from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiverclass User(models.Model):name = models.CharField(max_length=16)gender = models.CharField(max_length=32, blank=True)def create_user(sender, instance, created, **kwargs):if created:print("New user created!")
post_save.connect(create_user, sender=User)

在上例中我们使用了信号(post_save)自带的connect的方法将自定义的函数与信号发出者(sender)User模型进行了连接。在实际应用中一个更常用的方式是使用@receiver装饰器实现发送者与监听函数的连接,如下所示。@receiver(post_save, sender=User)读起来的意思就是监听User模型发出的post_save信号。

from django.db import models
from django.db.models.signals import post_save
from django.dispatch import receiverclass User(models.Model):name = models.CharField(max_length=16)gender = models.CharField(max_length=32, blank=True)@receiver(post_save, sender=User)
def create_user(sender, instance, created, **kwargs):if created:print("New user created!")

在Django中,request_started, request_finished, 和 got_request_exception 这三个信号可以用于在请求处理的不同阶段执行特定的代码逻辑,例如日志记录、性能监控、资源管理等。以下是使用这些信号的基本步骤:

#your_app/single.py
from django.core.signals import request_started, request_finished, got_request_exception
from django.dispatch import receiver@receiver(request_started)
def on_request_started(sender, environ, **kwargs):# 在这里添加处理逻辑,比如开始记录请求时间、初始化日志上下文等print("Request started.")@receiver(request_finished)
def on_request_finished(sender, **kwargs):# 在这里添加处理逻辑,比如记录请求结束时间、计算请求耗时、清理资源等print("Request finished.")@receiver(got_request_exception)
def on_request_exception(sender, request, **kwargs):# 在这里添加处理逻辑,比如记录异常信息、发送报警等print("Exception occurred during request processing:", request)

注册信号处理器:

# your_app/apps.py
from django.apps import AppConfig
from django.core.signals import request_started, request_finished, got_request_exception
from .signals import on_request_started, on_request_finished, on_request_exceptionclass YourAppConfig(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'your_app'def ready(self):# 注册信号处理器request_started.connect(on_request_started)request_finished.connect(on_request_finished)got_request_exception.connect(on_request_exception)

自定义信号

首先,你需要定义一个新的信号。这通常在应用的一个单独的signals.py文件中完成。信号通过django.dispatch.Signal类来定义,并可以指定信号发送时需要携带的参数。

#创建一个名为APP01的应用
# APP01/signals.py
from django.dispatch import Signal
from django.dispatch import receiver
# 定义一个自定义信号,提供额外的参数example_arg
my_custom_signal = Signal(providing_args=['example_arg'])#注册信号回调函数
@receiver(my_custom_signal)
def my_signal_handler(sender, **kwargs):example_arg = kwargs.get('example_arg', "No argument provided.")print(f"Custom signal received with argument: {example_arg}")# 在这里执行你的逻辑,比如记录日志、更新数据库、发送邮件等

然后注册信号处理器,你可以在应用的apps.py文件的ready()方法中注册这些信号处理器,确保它们在Django启动时被正确注册。

# APP01/apps.py
from django.apps import AppConfig
from .signals import my_signal_handlerclass YourAppConfig(AppConfig):default_auto_field = 'django.db.models.BigAutoField'name = 'your_app'def ready(self):# 连接信号处理器my_custom_signal.connect(my_signal_handler)

发送信号

# 例如,在某个视图中发送信号
from django.http import HttpResponse
from .signals import my_custom_signaldef some_view(request):# 执行某些操作...# 例如当用户成功登录的时候....my_custom_signal.send(sender=None, example_arg="This is an example argument.")return HttpResponse("Signal sent.")

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/20002.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

WiFi串口服务器与工业路由器:局域网应用的协同之力

在工业物联网(IIoT)迅猛发展的当下,局域网(LAN)作为连接工业设备与数据中心的桥梁,其重要性日益凸显。WiFi串口服务器与工业路由器作为局域网中的关键组件,以其独特的性能和功能,为传…

64位和32位对C++ 对long类型的使用造成程序崩溃、内存泄漏问题。

系列文章目录 1、理解32位和64位下long类型和int类型不同 2、理解release和debug版本编译的可执行程序的区别 3、谨慎在64位下对long类型与int类型去赋值和相互转换 文章目录 系列文章目录前言一、int、long类型二、使用步骤1.示例代码 前言 编译环境:qt -c、linu…

cURL error 60: SSL certificate problem: unable to get local issuer certifica

本地小程序把接口换到本地的服务器接口,然后就报错了: cURL error 60: SSL certificate problem: unable to get local issuer certificate (see https://curl.haxx.se/libcurl/c/libcurl-errors.html) 经查询查到:此问题的出现是由于没有配…

Nginx企业级负载均衡:技术详解系列(14)—— 账户认证功能

你好,我是赵兴晨,97年文科程序员。 你有没有听说过Nginx的账户认证功能?这可不只是一个技术问题,它关系到我们上网时的安全和便利。就像家里需要一把钥匙才能进们一样,Nginx的账户认证功能就是确保有只有授权的人才能…

Android Studio启动第一个项目的报错——笔记

零基础第一次使用Android Studio开发遇到的问题 1 新建项目下载gradle慢的问题 直接叉掉打开gradle官网手动下载自己想要的版本 gradle官网 然后在刚刚建好的项目里找到gradle-wrapper.properties,修改distributionUrl,并把自己从官网下载的包放到和gr…

Scroll 上的明星项目Pencils Protocol ,缘何被严重低估?

近日,完成品牌升级的 Pencils Prtocol 结束了 Season 2 并无缝开启了 Season 3,在 Season 3 中,用户可以通过质押系列资产包括 $ETH、$USDT、$USDC、$STONE 、$wrsETH、$pufETH 等来获得可观收益,并获得包括 Scroll Marks、 Penci…

【运维项目经历|023】Docker自动化部署与监控项目

目录 项目名称 项目背景 项目目标 项目成果 我的角色与职责 我主要完成的工作内容 本次项目涉及的技术 本次项目遇到的问题与解决方法 本次项目中可能被面试官问到的问题 问题1:项目周期是多久? 问题2:服务器部署架构方式及数量配置…

【Nacos源码分析01-服务注册与集群间数据是同步】

文章目录 了解CAPBASE理论Nacos支持CP还是AP集群数据同步实现集群数据一致性源码 了解CAP CAP理论的核心观点是,一个分布式系统无法同时完全满足一致性、可用性和分区容错性这三个特性。具体而言,当发生网络分区时,系统必须在一致性和可用性之…

计算机视觉与模式识别实验1-2 图像的形态学操作

文章目录 🧡🧡实验流程🧡🧡1.图像膨胀2.图像腐蚀3.膨胀与腐蚀的综合使用4.对下面二值图像的目标提取骨架,并分析骨架结构。 🧡🧡全部代码🧡🧡 🧡&#x1f9e1…

tomcat中管理环境变量之setenv.sh

tomcat配置spring profiles springboot打包war部署到外部tomcat的时候指定profile启动 windows 在%tomcat%/bin下创建setenv.bat文件 linux 在%tomcat%/bin下创建setenv.sh文件 使用JVM参数: windows set "JAVA_OPTS%JAVA_OPTS% -Dspring.profiles.activedev"in…

Python自动化办公2.0 即将发布

第一节课:数据整理与清洗 第二节课:数据筛选、过滤与排序 第三节课:高级数据处理技巧 第四节课:数据可视化与实践案例 第五节课:统计分析与报表 第六节:常见的Excel报表 与下方的课程形成知识体系&…

vue3学习(六)

前言 接上一篇学习笔记,今天主要是抽空学习了vue的状态管理,这里学习的是vuex,版本4.1。学习还没有学习完,里面有大坑,难怪现在官网出的状态管理用Pinia。 一、vuex状态管理知识点 上面的方式没有写全,还有…

如何在Windows 10上更改默认系统字体,这里有详细步骤

Windows 10的默认系统字体Segoe UI看起来相当不错。但是,如果你有更好的替代品,你可以更改Windows 10 PC上的默认系统字体。我们将向你展示如何执行此操作。 如何使用注册表编辑器更改默认系统字体 在撰写本文时,“设置”和“控制面板”都没有更改默认系统字体的选项。这意…

官网:管它日薄西山or蒸蒸日上,气质这块,必须拿捏死死的。

在日薄西山的时候,网站建设面临着许多困难和挑战。市场竞争激烈,用户需求多样化,技术更新迅速,这些都要求我们在网站建设中拥有高尚的气质。 而在蒸蒸日上的时刻,网站建设同样需要我们拿捏好气质。只有坚持下去&#…

软件和系统集成项目确认测试报告的费用需要多少?

确认测试报告 软件和系统集成项目确认测试报告的费用因多种因素而异,包括项目的规模、复杂度、测试范围、测试周期等。第三方软件测试机构价格区间一般是几千到几万不等,还有些会根据建设费用的2-5%进行收费。 一般来说,软件和系统集成项目…

element ui el-calendar日历组件完整代码

el-calendar日历组件完整代码 1. 说在前面2. 日历整体代码3. 编辑与新增 1. 说在前面 最近一直忙于上班,没咋看博客,发现很多小伙伴都要日历组件的代码,于是今天抽空给大家整理一下,为爱发电!日历组件的原文在这里&am…

计算机视觉与模式识别实验1-1 图像的直方图平衡

文章目录 🧡🧡实验流程🧡🧡1.读入图像‘rice.png’,在一个窗口中显示灰度级n64,128和256的图像直方图。2.调解图像灰度范围,观察变换后的图像及其直方图的变化。3.分别对图像‘pout.tif’和‘ti…

③单细胞学习-pbmc的Seurat 流程

目录 1,数据读取 2,线粒体基因查看 3,数据标准化 4,识别高变基因 5,进行数据归一化 6,进行线性降维 7,确定细胞簇 8,UMAP/tSNE降维(保存pbmc_tutorial.rds&#…

mirth Connect 自定义JAVA_HOME

mirth Connect 自定义JAVA_HOME 1、背景 服务器上安装了两个不同版本的Java,我希望Mirth服务使用与默认系统不同的版本。自定义指定java版本 2、解决方法 2.1 优先级说明 系统变量JAVA_HOME (设置后,mirth会根据这个进行启动运行服务,优先级…

【火炬打宝策略】

打宝策略刷遗物: 时可4 只刷奇诊加稀有度,没有奇诊可以直接不打。