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

 更新时间:2020年07月26日 09:42:46   作者:画星星高手  
这篇文章主要介绍了3分钟看懂Python后端必须知道的Django的信号机制,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

概念

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/

到此这篇关于3分钟看懂Python后端必须知道的Django的信号机制的文章就介绍到这了,更多相关Django 信号机制内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Python可执行文件反编译教程(exe转py)

    Python可执行文件反编译教程(exe转py)

    python的便利性,使得如今许多软件开发者、黑客都开始使用python打包成exe的方式进行程序的发布,那么Python如何反编译可执行文件,本文就来介绍一下,感兴趣的可以了解一下
    2021-12-12
  • Python rstrip()方法实例详解

    Python rstrip()方法实例详解

    这篇文章主要介绍了Python rstrip()方法,包括rstrip方法的语法介绍和参数类型,需要的朋友可以参考下
    2018-11-11
  • pycharm中出现no module named xlwt的原因及解决

    pycharm中出现no module named xlwt的原因及解决

    这篇文章主要介绍了pycharm中出现no module named xlwt的原因及解决方案,具有很好的参考价值,希望对大家有所帮助。
    2023-05-05
  • Python爬虫爬取微信朋友圈

    Python爬虫爬取微信朋友圈

    这篇文章主要介绍了Python爬虫爬取微信朋友圈的方法,文中讲解非常细致,帮助大家更好的理解和学习Python爬虫,感兴趣的朋友可以了解下
    2020-08-08
  • python肯德尔系数相关性数据分析示例

    python肯德尔系数相关性数据分析示例

    这篇文章主要为大家介绍了python肯德尔系数相关性数据分析示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-02-02
  • Python如何在脚本中设置环境变量

    Python如何在脚本中设置环境变量

    环境变量是与系统进程交互的一种深入方式,它允许用户获得有关系统属性、路径和已经存在的变量的更详细信息,下面我们就来看看Python是如何通过脚本来设置环境变量的吧
    2023-10-10
  • python 实现目录复制的三种小结

    python 实现目录复制的三种小结

    今天小编就为大家分享一篇python 实现目录复制的三种小结,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-12-12
  • 用Python写一个自动木马程序

    用Python写一个自动木马程序

    这篇文章主要介绍了用Python写一个自动木马程序的方法,本文给大家介绍的非常详细,具有一定的参考借鉴价值,需要的朋友可以参考下
    2019-09-09
  • Python离线安装第三方库详细操作流程

    Python离线安装第三方库详细操作流程

    在使用Python开发过程中,我们经常需要使用各种第三方库来扩展Python的功能,这篇文章主要给大家介绍了关于Python离线安装第三方库的相关资料,需要的朋友可以参考下
    2023-11-11
  • 浅谈Pycharm中的Python Console与Terminal

    浅谈Pycharm中的Python Console与Terminal

    今天小编就为大家分享一篇浅谈Pycharm中的Python Console与Terminal,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-01-01

最新评论