django 信号singals详解

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

django信号(singals)应用范围:

  • django中singals机制不是异步执行,而是同步执行,所以需要异步执行耗时的任务,不建议使用django自带对的singals。

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

  • 主要是解耦那些多次重复场合被调用的函数。直接用事件挂钩的方式被调用,这可以让你的代码更干净。

  • 异步任务,可以使用django的channels机制

应用案例:

  • 通知类 

    • 通知是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信号简单使用(django==2.1.1)

1.信号定义

所有信号都是django.core.signals.Singal的实例,providing_args是一个列表,由信号提供监听者的参数名称组成

# 两种引用方式
from django.core.signals import Signal
from django.dispatch import Signal

# 定义邮件发送信号
email_send = Singal(providing_args=['email'])

2.信号处理函数

from django.dispatch import Signal, receiver

# 定义邮件发送信号
email_send = Singal(providing_args=['email'])

# 处理函数
@receiver(email_send )
def send_email(sender, **kwargs):
    """发送邮件处理函数"""
    print("email_send信号处理函数被调用")

3.信号连接

信号连接就是将信号和处理函数连接起来,信号连接一般是在子应用配置类的ready方法进行操作

class TestAppConfig(object):
    def ready(self):
        # 信号连接
        email_send.connect(send_email)

4.自定义信号

from django.dispatch import Signal,receiver

# 定义邮件发送信号
email_send = Singal(providing_args=['email'])

# 处理函数
@receiver(email_send )
def send_email(sender, **kwargs):
    """发送邮件处理函数"""
    print("email_send信号处理函数被调用")
    
# 调用信号函数
class Test(Object):
    """ 其他具体代码"""
    
    # 调用邮件发送信号
    send_email(sender=self.__class__,username=username)

文档:

https://docs.djangoproject.com/en/1.11/topics/signals/

https://segmentfault.com/a/1190000008455657

相关文章

注:所有源代码均实测运行过。所有源代码均已上传CSDN,请有...
继承APIView和ViewSetMixin;作用也与APIView基本类似,提供...
一、Django介绍Python下有许多款不同的 Web 框架。Django是重...
本文从nginx快速掌握到使用,gunicorn快速掌握到使用,实现小...
uniapp微信小程序订阅消息发送服务通知
Django终端打印SQL语句 1 Setting配置: 2 默认python 使用的...