什么是django的signal

官方文档描述如下:

Django includes a “signal dispatcher” which helps allow decoupled applications get notified when actions occur elsewhere in the framework.In a nutshell, signals allow certain senders to notify a set of receivers that some action has taken place. They’re especially useful when many pieces of code may be interested in the same events.

Django内部包含了一位“信号调度员”:当某事件在框架内发生时,它可以通知到我们的应用程序。 简而言之,当event(事件)发生时,signals(信号)允许若干 senders(寄件人)通知一组 receivers(接收者)。这在我们多个独立的应用代码对同一事件的发生都感兴趣时,特别有用。

个人理解,django的signal可理解为django内部的钩子,当一个事件发生时,其他程序可对其作出相关反应,可通过signal来回调定义好的处理函数(receivers),从而更大程度的解耦我们的系统。

最佳使用场景

通知类 

通知是signal最常用的场景之一。例如,在论坛中,在帖子得到回复时,通知楼主。从技术上来讲,我们可以将通知逻辑放在回复保存时,但是这并不是一个好的处理方式,这样会时程序耦合度增大,不利于系统的后期扩展维护。如果我们在回复保存时,只发一个简单的信号,外部的通知逻辑拿到信号后,再发送通知,这样回复的逻辑和通知的逻辑做到了分开,后期维护扩展都比较容易。

初始化类

信号的另一个列子便是事件完成后,做一系列的初始化工作。

其他一些使用场景总结

以下情况不要使用signal:

  • signal与一个model紧密相关, 并能移到该model的save()时

  • signal能使用model manager代替时

  • signal与一个view紧密相关, 并能移到该view中时

以下情况可以使用signal:

  • signal的receiver需要同时修改对多个model时

  • 将多个app的相同signal引到同一receiver中处理时

  • 在某一model保存之后将cache清除时

  • 无法使用其他方法, 但需要一个被调函数来处理某些问题时

如何使用

django 的 signal 使用可分为2个模块:

  • signal :signal定义及触发事件

  • receiver : signal 接受函数

内建signal的使用

django 内部有些定义好的signal供我们使用:

模型相关:

  • pre_save 对象save前触发

  • post_save 对象save后触发

  • pre_delete 对象delete前触发

  • post_delete 对象delete后触发

  • m2m_changed ManyToManyField 字段更新后触发

请求相关:

  • request_started 一个request请求前触发

  • request_finished request请求后触发

针对django自带的signal,我们只需要编写receiver 即可,使用如下。

第一步,编写receiver并绑定到signal

myapp/signals/handlers.py

from django.dispatch import receiver
from django.core.signals import request_finished## decorators 方式绑定
@receiver(request_finished, dispatch_uid="request_finished")
def my_signal_handler(sender, **kwargs):print("Request finished!================================") # 普通绑定方式
def my_signal_handler(sender, **kwargs):print("Request finished!================================")request_finished.connect(my_signal_handler)#####################################################
# 针对model 的signal
from django.dispatch import receiver
from django.db.models.signals import post_savefrom polls.models import MyModel@receiver(post_save, sender=MyModel, dispatch_uid="mymodel_post_save")
def my_model_handler(sender, **kwargs):print('Saved: {}'.format(kwargs['instance'].__dict__))

dispatch_uid 确保此receiver 只调用一次

第二步,加载signal

*myapp/__init__py*


default_app_config = 'myapp.apps.MySendingAppConfig'

myapp/apps.py

from django.apps import AppConfigclass MyAppConfig(AppConfig):name = 'myapp'def ready(self):# signals are imported, so that they are defined and can be usedimport myapp.signals.handlers

到此,当系统受到request 请求完成后,便会执行receiver。

其他内建的signal,参考官方文档:

自定义signal的使用

自定义signal,需要我们编写 signal和 receiver 。

第一步, 编写signal

myapp.signals.signals.py


import django.dispatchmy_signal = django.dispatch.Signal(providing_args=["my_signal_arg1", "my_signal_arg_2"])

第二步,加载signal

*myapp/____init____py*

default_app_config = 'myapp.apps.MySendingAppConfig'

myapp/apps.py


from django.apps import AppConfigclass MyAppConfig(AppConfig):name = 'myapp'def ready(self):# signals are imported, so that they are defined and can be usedimport myapp.signals.handlers

第三步,事件触发时,发送signal

myapp/views.py


from .signals.signals import my_signalmy_signal.send(sender="some function or class",my_signal_arg1="something", my_signal_arg_2="something else"])

自定义的signal,django已经为我们编写了此处的事件监听。

第四步,收到signal,执行receiver

myapp/signals/handlers.py

from django.dispatch import receiver
from myapp.signals.signals import my_signal@receiver(my_signal, dispatch_uid="my_signal_receiver")
def my_signal_handler(sender, **kwargs):print('my_signal received')

此时,我们自定义的signal 便开发完成了。

总结

  • django signal 的处理是同步的,勿用于处理大批量任务。

  • django signal 对程序的解耦、代码的复用及维护性有很大的帮助。

原文链接

转载于:https://www.cnblogs.com/fzw-/p/8972878.html

Django signal相关推荐

  1. Django Signal 代码布局

    需要确保信号注册函数在使用前就被引入,所以理论上你可以将其置于满足上述条件的任意位置. 官方推荐 将信号处理器定义在关联 app 目录下的 signals.py 中,在关联 app 的 apps.Ap ...

  2. 测试django_如何像专业人士一样测试Django Signals

    测试django by Haki Benita 通过Haki Benita 如何像专业人士一样测试Django Signals (How to test Django Signals like a p ...

  3. 组合键 发送指定信号_Django signal 信号机制的使用

    Django中提供了"信号调度",用于在框架执行操作时解耦,当某些动作发生的时候,系统会根据信号定义的函数执行相应的操作 一.Django中内置的 signal 类型主要包含以下几 ...

  4. django Signals

    前言 在平时应用中我们经常遇到比如新增加一个用户就发送短信,新增加一条留言就给我们 发送邮箱 这种需求,一般来说都可以在视图函数中完成这些操作.但是如果有多个地方都需要类似的操作,比如用户在N个应用中 ...

  5. django 信号 signal

    转载请表明原文地址:http://www.liujiangblog.com/course/django/170 django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件 ...

  6. Django源码分析8:单元测试test命令浅析

    django源码分析 本文环境python3.5.2,django1.10.x系列 django源码分析-test命令分析 Django项目中提供了,test命令行命令来执行django的单元测试,该 ...

  7. Django源码分析7:migrate命令的浅析

    django源码分析 本文环境python3.5.2,django1.10.x系列 django源码分析-migrate命令分析 Django项目中提供了,通过migrations操作数据库的结构的命 ...

  8. Django源码分析4:staticfiles静态文件处理中间件分析

    django源码分析 本文环境python3.5.2,django1.10.x系列1.在上一篇文章中已经分析过handler的处理过程,其中load_middleware就是将配置的中间件进行初始化, ...

  9. Django缓存和信号

    Django进阶之缓存和信号 一.缓存 简介 由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用:缓存,缓存将一个某个view ...

最新文章

  1. k-means优化 k-means距离的选择 k-medoids对比
  2. 手机型号大全资料_电子元器件知识资料大全
  3. JavaScript setTimeout函数
  4. 【读书笔记】Android的Ashmem机制学习
  5. 你真的会用ABAP, Java和JavaScript里的constructor么?
  6. 61 SD配置-科目分配-分配税收确定的交货工厂
  7. Kafka 消息序列化反序列化
  8. Fedora23 安装 psycopg2
  9. crackme--Cruehead-CrackMe-3
  10. 手机电视一CMMB系统技术应用浅谈
  11. 笔记本开热点自动断开
  12. armbian清理_N1刷入Armbian后保护emmc – 禁止varlog日志
  13. js和jquery获取父级元素、子级元素、兄弟元素的方法
  14. 英文单词之说文解字(10)你真的用对“著名”了吗?
  15. 长春有学计算机的中专吗,长春比较好的中专学校
  16. 物联网卡开启养老新模式
  17. ue4 开发动作游戏_ue4游戏开发虚幻4学习教程资源素材合集
  18. 广电网宽带 如果要远程连接阿里RDS数据库,设置了白名单也不行。
  19. 长期表现决定了最终结果--leo看赢在中国第三季(8)大结局
  20. 今天睡眠质量记录74分

热门文章

  1. python发邮件实例_python发邮件实例
  2. springMVC从发送hello请求到响应的执行流程分析
  3. 前端 获取当前页面服务器ip_fiddler获取响应时间以及服务器IP
  4. 算法学习--二叉查找树
  5. 大规模文本分类实验-项目日志
  6. 网站 测试服务器配置,安装调试、软件测试、网站测试 配置维护环境配置、安全维护、安全运维等与服务器相关业务...
  7. exec 直接赋值_了解 JavaScript 解构赋值
  8. [网址链接]格林童话故事的原始素材
  9. mysql——启动服务问题Found option without preceding group in config file
  10. golang 内存分析/动态追踪