一、什麼是信號(Signals)
官方定義見參考資料[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 :在可能發送重複信號的情況下,信號接收器的唯一標識符。
1.編寫receiver並綁定到signal
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消息
2.加載signal
myapp/views.py
# views.py和handlers.py屬於同一目錄層級,也可以直接把create_msg_handler()寫到views.py裏面,然後就不用導入了。 from . import handlers
三、爲什麼使用信號Signals
當然,我們也可以不用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/