官方定义见参考资料[1]。以下是个人理解:django signals是一种机制——当某个动作(action)发生时,信号(signal)允许发送器(senders)通知到接收器(receivers)。
示例:当某篇文章被评论时,生成一条消息,通知到文章的作者,告诉作者文章有人评论了。
Django提供了一整套内置信号,详见参考资料[2]。如:
django.db.models.signals.post_save(在ORM模型的save()方法调用之前或之后发送信号)要接收信号,需要将receiver注册到signals(将signals和receivers绑定)。可以使用Signal.connect()(Signals的connect()方法)进行注册。
方法:
Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)[source]
注:此处Signal指的是信号实例,如Django的内置信号post_save。 参数说明: receiver :接收器,是一个回调函数。 sender :发送器。 weak : 是否弱引用 dispatch_uid :在可能发送重复信号的情况下,信号接收器的唯一标识符。myapp/handlers.py
from django.db.models.signals import post_save from django.dispatch import receiver from .models import Comment # 评论模型
# 方式一:使用装饰器进行绑定 @receiver(post_save, sender=Comment) #只接收Comment发来的post_save消息 def create_msg_handler(sender, instance, **kwargs): article = instance.belong # instance 就是发信号的对象,这里是个评论 sender = instance.owner # 获取评论者,即消息发送者 receiver = article.author # 通知文章作者 msg = Message(sender=sender, receiver=receiver, belong=instance) # 新建消息保存 msg.save() # 方式二:普通绑定 def create_msg_handler(sender, instance, **kwargs): article = instance.belong # instance 就是发信号的对象,这里是个评论 sender = instance.owner # 获取评论者,即消息发送者 receiver = article.author # 通知文章作者 msg = Message(sender=sender, receiver=receiver, belong=instance) # 新建消息保存 msg.save()
post_save.connect(my_callback, sender=Comment) # 只接收Comment发来的post_save消息
myapp/views.py
# views.py和handlers.py属于同一目录层级,也可以直接把create_msg_handler()写到views.py里面,然后就不用导入了。 from . import handlers当然,我们也可以不用signal,在评论保存之后,直接生成一条通知消息。但是如果有多个sender对一个receiver的时候,这时候就得写重复的代码了,此时则可以使用signal。从而更大程度的解耦我们的系统。
[1] Django官方文档,Sinals:https://docs.djangoproject.com/en/2.2/topics/signals/
[2] Django官方文档,built-in Sinals:https://docs.djangoproject.com/en/2.2/ref/signals/