djnago信號的簡單介紹

Django的singals

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提供一組內建的信號,允許用戶的代碼獲得Django特定操作的通知。 它們包含一些有用的通知:
* django.db.models.signals.pre_save&django.db.models.signals.post_save

  在模型 save()方法調用之前或之後發送。

* django.db.models.signals.pre_delete&django.db.models.signals.post_delete

   在模型delete()方法或查詢集的delete() 方法調用之前或之後發送。

* django.db.models.signals.m2m_changed

   模型上的 ManyToManyField 修改時發送。

* django.core.signals.request_started&django.core.signals.request_finished

  Django開始或完成HTTP請求時發送。

關於完整列表以及每個信號的完整解釋,請見內建信號的文檔 。
文檔鏈接

使用信號的方法

1、在與models.py同級的目錄下新建siginals文件

2、在signals文件中定義觸發函數,將函數與信號綁定起來

我使用了post_save,在模型實例調用save方法後,會觸發save_user函數。
instance表示保存的模型實例,在這裏是UserProfile實例。created表示這個實例是否第一次創建

from django.db.models import signals
from django.dispatch import receiver

# 裝飾器方式
@receiver(signals.post_save, sender=UserProfile)
def save_user(instance, created, **kwargs):
    if created:
        print('創建了一條記錄')
    else:
        print('修改了一條記錄')

# 手動連接方式
def save_user(...):
    ......
signals.post_save.connect(save_user, UserProfile)

目前爲止,配置還沒有結束。之前照着文檔步驟始終不能觸發信號,頭疼了好久。是因爲還缺少了配置ready的一步

文檔有這樣一段話

Where should this code live?

Strictly speaking, signal handling and registration code can live anywhere you like, although it’s recommended to avoid the application’s root module and its models module to minimize side-effects of importing code.

In practice, signal handlers are usually defined in a signals submodule of the application they relate to. Signal receivers are connected in the ready() method of your application configuration class. If you’re using the receiver() decorator,simply import the signals submodule inside ready().

大概含義是要在ready中導入信號,不懂,搜索了下配置寫在下面

3、加載signal

/myapp/init.py

default_app_config = 'users.apps.UsersConfig'

/myapp/apps.py

class UsersConfig(AppConfig):
    name = 'users'

    def ready(self):
        import users.signals

經過以上三步就完成配置,在admin中修改記錄,運行結果放在下面:

a

[15/Sep/2018 23:39:17] "GET /static/admin/js/prepopulate_init.js HTTP/1.1" 304 0
[15/Sep/2018 23:39:17] "GET /favicon.ico HTTP/1.1" 302 0
修改了一條記錄

總結下來,信號可以幫助我們解耦應用,比如保存一條記錄時,發送郵件通知。信號還支持自定義,有空補充完整。

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