1. 程式人生 > >django(12)、信號

django(12)、信號

ron req int action 基類 數據 finish let chang

內置信號

pre_init            # Django中的model對象執行其構造方法前,自動觸發
post_init           # Django中的model對象執行其構造方法後,自動觸發
pre_save            # Django中的model對象保存前,自動觸發
post_save           # Django中的model對象保存後,自動觸發
pre_delete          # Django中的model對象刪除前,自動觸發
post_delete         # Django中的model對象刪除後,自動觸發
m2m_changed         #Django中的model對象使用m2m字段操作數據庫的第三張表(add,remove,clear,update),自動觸發
class_prepared    # 程序啟動時,檢測到已註冊的model類,對於每一個類,自動觸發
request_started     # 請求到來前,自動觸發
request_finished    # 請求結束後,自動觸發
got_request_exception           # 請求異常時,自動觸發
setting_changed     # 配置文件改變時,自動觸發
template_rendered   # 模板執行渲染操作時,自動觸發
connection_created  # 創建數據庫連接時,自動觸發

內置信號使用:以pre_savepost_save為例,

# 項目目錄 init.py

# 1、導入需要引用的內置信號
from django.db.models.signals import pre_save, post_save 


# 2、自定義功能函數
def pre_save_func(sender, **kwargs):
    print('pre_save_fun')
    print('pre_save_msg:', sender, kwargs)


def post_save_func(sender, **kwargs):
    print('post_save_func')
    print('post_save_msg:', sender,kwargs)


# 3、綁定功能函數到信號
pre_save.connect(pre_save_func)  # 在save對象前觸發
post_save.connect(post_save_func)  # 在save對象後觸發



# 4、打印結果
pre_save_fun
pre_save_msg: <class 'app01.models.Author'> {'signal': <django.db.models.signals.ModelSignal object at 0x0343F990>, 'instance': <Author: kate>, 'raw': False, 'using': 'default', 'update_fields': None}
post_save_func
post_save_msg: <class 'app01.models.Author'> {'signal': <django.db.models.signals.ModelSignal object at 0x0343F9F0>, 'instance': <Author: kate>, 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}

自定義信號

  • 1、創建文件, 定義信號:

    # /utils/signal_test.py
    # step1:實例化signal對象
    import django.dispatch
    action=django.dispatch.Signal(providing_args=["aaa","bbb"])
  • 2、在項目應用的init文件中完成功能函數和綁定信號

    # django_review\__init__.py
    from utils.signal_test import action
    
    # step2:定義receiver(A function or an instance method which is to receive signals.)
    def pre_save_func(sender, **kwargs):
        print("pre_save_func")
        print("pre_save_msg:", sender, kwargs)
    
    # step3:Connect receiver to sender for signal.
    action.connect(pre_save_func)
  • 3、在視圖函數中觸發信號

    from utils.signal_test import action
    
    
    def index(request):
        books = Book.objects.all()
        author = Author.objects.create(name='kate1',gender=1)
    
        # step4:發送信號到所有連接的reciever(Send signal from sender to all connected receivers.)
        action.send(sender='create', aaa=author.name, bbb=author.get_gender_display())
        return render(request, 'index.html', locals())
  • 4、結果展示

    pre_save_func
    pre_save_msg: create {'signal': <django.dispatch.dispatcher.Signal object at 0x04287370>, 'aaa': 'kate1', 'bbb': '女'}
    [09/Aug/2018 11:00:50] "GET / HTTP/1.1" 200 990

信號和中間件的區別

  • 信號比中間件散布的範圍更廣。
  • 在後臺的許多動作事件都可以觸發內置的信號,從而執行與之綁定的函數
  • 也可以自定義信號擴展其功能
  • 而中間件常用的就只有四個函數,且僅在接受請求和返回請求的過程中起作用

源碼分析

class Signal(object):
    """所有信號的基類"""
    
    def __init__(self, providing_args=None, use_caching=False):

        self.receivers = []
        if providing_args is None:
            providing_args = []
        self.providing_args = set(providing_args)

    def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
         """
        Connect receiver to sender for signal.
        
        Arguments:
            receiver
                A function or an instance method which is to receive signals.
                Receivers must be hashable objects.
        """
        pass

    def send(self, sender, **named):
        """
        Send signal from sender to all connected receivers.

        If any receiver raises an error, the error propagates back through send,
        terminating the dispatch loop. So it's possible that all receivers
        won't be called if an error is raised.

        Arguments:
            sender
                The sender of the signal. Either a specific object or None.

            named
                Named arguments which will be passed to receivers.
        Returns a list of tuple pairs [(receiver, response), ... ].
        """
        pass

django(12)、信號