目录

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. JAVA构造MAP并初始化MAP

    第一种方法:static块初始化 public class Demo{ private static final Map<String, String> myMap; static { m ...

  2. c++——this指针

    实验1:若类成员函数的形参 和 类的属性,名字相同,通过this指针来解决. 实验2:类的成员函数可通过const修饰,请问const修饰的是谁 #include <iostream> u ...

  3. 1363: Count 101 (经典数位dp)

    1363: Count 101 Submit Page    Summary    Time Limit: 1 Sec     Memory Limit: 128 Mb     Submitted: ...

  4. 故障排除--kubernetes 运维操作步骤 -- kubedns -- busybox -- nslookup 问题

    1.node的扩容 在k8s中,对一个新的node的加入非常简单,只需要在node节点上安装docker.kubelet和kube-proxy服务,然后将kubelet和kube-proxy的启动参数 ...

  5. nmap 扫描端口 + iftop 实时监控流量

    sleep 1|telnet 127.0.0.1 223 nmap 127.0.0.1 -p 223 -PN   (对禁ping IP) iftop -P -n -B -B 按字节显示 -N 切换 端 ...

  6. 50个国内外最棒的C/C++源码站点分享

    C/C++是最基本的编程语言.这里列出了50名优秀站点和网页清单,这些站点提供c/c++源码.这份清单提供了源码的链接以及它们的小说明.我已 尽力包含最佳的C/C++源码的站点.这不是一个完整的清单, ...

  7. OO第一次博客作业总结反思

    使用了masteruml插件来生成类图和metrics插件分析代码 第一次作业 1.UML类图 >在第一次作业中,使用了两个类,代码中有没有使用的变量与函数,为平衡两个类的内容,我将输出函数放在 ...

  8. #leetcode刷题之路48-旋转图像

    给定一个 n × n 的二维矩阵表示一个图像.将图像顺时针旋转 90 度.说明:你必须在原地旋转图像,这意味着你需要直接修改输入的二维矩阵.请不要使用另一个矩阵来旋转图像.示例 1:给定 matrix ...

  9. C语言 基础练习40

    一.题目 1.输入2个整数,求两数的平方和并输出. 2. 输入一个圆半径(r)当r>=0时,计算并输出圆的面积和周长,否则,输出提示信息. 3.函数y=f(x)可表示为: 4.编写一个程序,从4 ...

  10. Deep Learning综述[上]

    Deep-Learning-Papers-Reading-Roadmap: [1] LeCun, Yann, Yoshua Bengio, and Geoffrey Hinton. "Dee ...