Django信號Signals原理與示例(評論通知)

一、什麼是信號(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/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章