目录

Django信号介绍

Django内置信号

  • 信号种类
  • 信号注册

自定义信号

实测

  • 内置信号
  • 自定义信号

Django信号介绍

Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。

比如在数据库操作,插入一条数据之前和之后都写入日志。

这里装饰器就实现不了了,装饰器用在函数上,这里可能在一条代码前后,而且是每次。

Django是非常牛逼的框架,在很多地方都放置了钩子。我们调用钩子就可以了。

我们可以在信号里面注册很多个函数。触发信号时,会把信号里的函数执行一遍。

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内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

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}

Django_信号的更多相关文章

  1. Boost信号/槽signals2

    信号槽是Qt框架中一个重要的部分,主要用来解耦一组互相协作的类,使用起来非常方便.项目中有同事引入了第三方的信号槽机制,其实Boost本身就有信号/槽,而且Boost的模块相对来说更稳定. signa ...

  2. 为什么房间的 Wi-Fi 信号这么差

    最近把家里主卧整成了个小影院,由于之前房子装修时网线端口与电源插口布置太少,导致家庭网络架设变得麻烦起来,最后终于通过「无线中继」技术达到了全屋满格 Wi-Fi 的效果. 在 Wi-Fi 架设过程中, ...

  3. qt5中信号和槽的新语法

    qt5中的连接 有下列几种方式可以连接到信号上 旧语法 qt5将继续支持旧的语法去连接,在QObject对象上定义信号和槽函数,及任何继承QObjec的对象(包含QWidget). connect(s ...

  4. C# - 多线程 之 信号系统

    基础概览 多线程之信号系统命名空间 using System.Threading; 线程同步类的继承层次关系图 终止状态和非终止状态 在终止状态下,被WaitOne()阻塞的线程会逐个得到释放.如果一 ...

  5. Qt信号与槽自动关联机制

    参考链接1:http://blog.csdn.net/skyhawk452/article/details/6121407 参考链接2:http://blog.csdn.net/memory_exce ...

  6. Linux 信号(二)—— signal 函数

    弗洛伊德认为:要解决这些苦恼,当事人就要通过回忆并理解自己早期的童年经历,来获得对潜意识冲突的顿悟.弗洛伊德的疗法被称为“精神分析” (psychoanalysis),在 20 世纪的很长一段时间被心 ...

  7. Linux 信号(一)—— kill 函数

    世事并无好坏之分,全看我们怎么去想.—— 哈姆雷特·第二幕第二景 ilocker:关注 Android 安全(新入行,0基础) QQ: 2597294287 #include <signal.h ...

  8. django 缓存、中间件、信号、CSRF 详解

    中间件 django 中的中间件(middleware),在django中,中间件其实就是一个类,在请求到来和结束后,django会根据自己的规则在合适的时机执行中间件中相应的方法. 在django项 ...

  9. PHP进程通信基础——信号

    PHP进程通信基础--信号 使用信号通信.可以使用kill -l 来查看当前系统的信号类型. 每个信号所代表的的详细含义,请查看我的这篇博客:http://www.cnblogs.com/roverl ...

随机推荐

  1. TortoiseGit需要重复填写用户名和密码的问题

    命令行执行: git config --global credential.helper store 即可

  2. pytest 框架自动化Selenium 之yield 使用

    环境 python 3.7 由于3.0-3.5以下部分pytest可能有部分兼容问题安装建议2.7-2.9,3.5-最新 pip install pytest专属 pytest框架包 pip inst ...

  3. 学习JavaSE TCP/IP协议与搭建简易聊天室

    一.TCP/IP协议 1.TCP/IP协议包括TCP.IP和UDP等 2.域名通过dns服务器转换为IP地址 3.局域网可以通过IP或者主机地址寻找到相应的主机 4.TCP是可靠的连接,效率低,且连接 ...

  4. iOS Class结构分析

    objc_class结构体 类在OC中是objc_class的结构体指针 typedef struct objc_class *Class; 在objc/runtime.h中objc_class结构体 ...

  5. 1025 反转链表(链表,reverse)

    题目: 给定一个常数 K 以及一个单链表 L,请编写程序将 L 中每 K 个结点反转.例如:给定 L 为 1→2→3→4→5→6,K 为 3,则输出应该为 3→2→1→6→5→4:如果 K 为 4,则 ...

  6. jquery animate() Alternate 语法

    前段时间在使用jQuery的animate() 函数时候用到Alternate方式.主要是要让数字自增到指定大小,且能看见数字增加过程. 一般使用如下方式: function autoPlusAnim ...

  7. 【转载】WCF 客户端识别认证之UserName认证

    原文地址: http://blog.csdn.net/zxz414644665/article/details/9308055 过程:用户调用service,服务端验证用户传来的用户名和密码(传输过程 ...

  8. IceStorm示例运行步骤

    又一次忘了,记下: 1.启动IceStorm服务,输入:icebox --Ice.Config=config.icebox 启动IceStorm服务.2.消息接收:开启另一个命令行窗口,Subscri ...

  9. 【LG3247】[HNOI2016]最小公倍数

    [LG3247][HNOI2016]最小公倍数 题面 洛谷 题解 50pts 因为拼凑起来的部分分比较多,所以就放一起了. 以下设询问的\(a,b\)为\(A,B\), 复杂度\(O(nm)\)的:将 ...

  10. 洛咕 P2494 [SDOI2011]保密

    出题人没素质啊,强行拼题还把题面写得又臭又长. 简单题面就是有一张图,每条边有两个权值\(t,s\),有无限支军队,一支军队可以打一个点,代价是从n到这个点的路径的\(\frac{\sum t}{\s ...