Django_信號

目錄

Django信號介紹html

Django內置信號數據庫

  • 信號種類
  • 信號註冊

自定義信號django

實測app

  • 內置信號
  • 自定義信號

Django信號介紹

Django中提供了「信號調度」,用於在框架執行操做時解耦。通俗來說,就是一些動做發生的時候,信號容許特定的發送者去提醒一些接受者。框架

好比在數據庫操做,插入一條數據以前和以後都寫入日誌。ide

這裏裝飾器就實現不了了,裝飾器用在函數上,這裏可能在一條代碼先後,並且是每次。函數

Django是很是牛逼的框架,在不少地方都放置了鉤子。咱們調用鉤子就能夠了。post

咱們能夠在信號裏面註冊不少個函數。觸發信號時,會把信號裏的函數執行一遍。測試

Django內置信號

信號種類

# Model signals
/    pre_init                # django的modal執行其構造方法前,自動觸發
\    post_init               # django的modal執行其構造方法後,自動觸發
/    pre_save                # django的modal對象保存前,自動觸發
\    post_save               # django的modal對象保存後,自動觸發
/    pre_delete              # django的modal對象刪除前,自動觸發
\    post_delete             # django的modal對象刪除後,自動觸發
    m2m_changed              # django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發
    class_prepared           # 程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發
# Management signals
    pre_migrate              # 執行migrate命令前,自動觸發
    post_migrate             # 執行migrate命令後,自動觸發
# Request/response signals
    request_started          # 請求到來前,自動觸發
    request_finished         # 請求結束後,自動觸發
    got_request_exception    # 請求異常後,自動觸發
# Test signals
    setting_changed          # 使用test測試修改配置文件時,自動觸發
    template_rendered        # 使用test測試渲染模板時,自動觸發
# Database Wrappers
    connection_created       # 建立數據庫鏈接時,自動觸發

信號註冊

對於Django內置的信號,僅需註冊指定信號,當程序執行相應操做時,自動觸發註冊函數:spa

from django.core.signals import request_started
from django.core.signals import request_finished
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created

################### 方法一 xxoo.connect(func) ###################
def func1(sender,*args, **kwargs):
    print("request_started_func1")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

def func2(sender,*args, **kwargs):
    print("request_finished_func2")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

request_started.connect(func1)  # 信號註冊函數func1。request_started指上述導入的信號
request_finished.connect(func2)  # 信號註冊函數func2。request_finished指上述導入的信號

################### 方法二 @receiver(xxoo)###################
from django.core.signals import request_started
from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_started)
def func3(sender,*args, **kwargs):
    print("request_started_func3")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

@receiver(request_finished)
def func4(sender,*args, **kwargs):
    print("request_finished_func4")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

如何調用執行

  • views.py裏直接寫入上述代碼
  • __init__.py寫入上述代碼(推薦):能夠在project下的同名目錄下__init__.py裏導入這個文件,這樣一運行就自動註冊了

 

自定義信號

定義信號

import django.dispatch
sg_name = django.dispatch.Signal(providing_args=["toppings", "size"])  # 觸發信號至少要傳兩個參數

註冊信號

def callback(sender, **kwargs):
    print("callback")
    print(sender,kwargs)

sg_name.connect(callback)

觸發信號

from 路徑 import sg_name

sg_name.send(sender='發送者隨便填',toppings=123, size=456)

因爲內置信號的觸發者已經集成到Django中,因此其會自動調用,而對於自定義信號則須要開發者在任意位置觸發。

好比對系統狀態閥值設置,到達某個狀態,觸發信號。

這樣只註冊信號就能夠,相似插拔式,下降程序耦合。

 

實測

內置信號

from django.core.signals import request_started
from django.core.signals import request_finished
from django.core.signals import got_request_exception

from django.db.models.signals import class_prepared
from django.db.models.signals import pre_init, post_init
from django.db.models.signals import pre_save, post_save
from django.db.models.signals import pre_delete, post_delete
from django.db.models.signals import m2m_changed
from django.db.models.signals import pre_migrate, post_migrate

from django.test.signals import setting_changed
from django.test.signals import template_rendered

from django.db.backends.signals import connection_created

################### 方法一 xxoo.connect(func) ###################
def func1(sender,*args, **kwargs):
    print("request_started_func1")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

def func2(sender,*args, **kwargs):
    print("request_finished_func2")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

request_started.connect(func1)  # 信號註冊函數func1。request_started指上述導入的信號
request_finished.connect(func2)  # 信號註冊函數func2。request_finished指上述導入的信號

################### 方法二 @receiver(xxoo)###################
from django.core.signals import request_started
from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_started)
def func3(sender,*args, **kwargs):
    print("request_started_func3")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號

@receiver(request_finished)
def func4(sender,*args, **kwargs):
    print("request_finished_func4")
    print(sender,args,kwargs)  # 兩個參數會把內容傳遞給信號
__init__.py
from django.shortcuts import render,HttpResponse
import time

def index(request):
    ctime = time.time()
    print("index.html")
    return render(request,"index1.html",{"ctime":ctime})
views.py
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <h2>{{ ctime }}</h2>
</body>
</html>
index1.html
# 結果
request_started_func1
<class 'django.core.handlers.wsgi.WSGIHandler'> () {'signal': <django.dispatch.dispatcher.Signal object at 0x09CD0950>, 'environ': ...略}}
request_started_func3
<class 'django.core.handlers.wsgi.WSGIHandler'> () {'signal': <django.dispatch.dispatcher.Signal object at 0x09CD0950>, 'environ': ...略}}
index.html
request_finished_func2
<class 'django.core.handlers.wsgi.WSGIHandler'> () {'signal': <django.dispatch.dispatcher.Signal object at 0x09CD0970>}
request_finished_func4
<class 'django.core.handlers.wsgi.WSGIHandler'> () {'signal': <django.dispatch.dispatcher.Signal object at 0x09CD0970>}

自定義信號

import django.dispatch
sg_name = django.dispatch.Signal(providing_args=["toppings", "size"])  # 觸發信號至少要傳兩個參數


def callback(sender, **kwargs):
    print("callback")
    print(sender,kwargs)

sg_name.connect(callback)
__init__.py
from . import sg_name


from django.shortcuts import render,HttpResponse
import time

def index(request):
    ctime = time.time()
    print("index.html")
    sg_name.send(sender='發送者隨便填', toppings=123, size=456)  # 須要手動觸發
    return render(request,"index1.html",{"ctime":ctime})
views.py
# 結果

index.html
callback
發送者隨便填 {'signal': <django.dispatch.dispatcher.Signal object at 0x0A6BFC30>, 'toppings': 123, 'size': 456}
相關文章
相關標籤/搜索