Django 信号

django自带一套信号机制来帮助我们在框架的不同位置之间传递信息。也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发送给一组接受者(receivers)

信号系统三要素:

  • 信号 <class: django.dispatch.Signal > 的实例
  • 发送方 某一个信号的发送者
  • 接收方 一个或多个信号的接收者

信号的分类:

  • Django 内置信号, 框架内置的 Signal 实例, 发送 方 为 Django 框架
  • 自定义 信号 , 开发者 手动创建 Signal 实例, 且需指定发送方 和 接收方

Django 内置信号:

框架位置: 位于框架 signals.py 文件中。 例如 框架内置的各 app 目录下的 django\contrib\APP\signals.py 文件中 和django\core\signals.py 文件中。

# 在ORM模型的save()方法调用之前或之后发送信号:
django.db.models.signals.pre_save
django.db.models.signals.post_save
# 在ORM模型或查询集的delete()方法调用之前或之后发送信号:
django.db.models.signals.pre_delete
django.db.models.signals.post_delete
# 当多对多字段被修改时发送信号:
django.db.models.signals.m2m_changed
# 当接收和关闭HTTP请求时发送信号:
django.core.signals.request_started
django.core.signals.request_finished
# 规律 : 以 'pre' 开头的 代表动作之前的, 而以 'post' 开头 代表动作之后的

具体 Django 信号内容

定义信号

所有的信号都是django.dispatch.Signal的实例

方法原型:

def __init__(self, providing_args=None, use_caching=False):[source]
"""
providing_args: 信号提供 给接收者 的参数列表
use_caching :是否对于每个不同的发送者缓存发送者所拥有的接收者
"""
# 注意: 参数可都为空

发送信号

Django中有两种方法用于发送信号。

Signal.send(sender, **kwargs)[source]

Signal.send_robust(sender,** kwargs)[source]
"""
注意: 1. 必须提供 sender 参数(大部分情况下是一个类名), 表明 发送方的身份
2. 可以提供任意数量的其他关键字参数
"""

send()和send_robust()返回一个元组对的列表[(receiver, response), ... ],表示接收器和响应值二元元组的列表。

例如: 在视图 函数可定义如下

class Panda(View):
def get(self,request):
Signal.send(sender=self.__class__,) ##
return HttpResponse("shiwei is Good") def post(self, request):
Signal.send_robust(sender=self.__class__) ##
return JsonResponse({
"code": 200,
'msg': "is Successful",
})

接收信号

Django 使用 Signal 实例的 connect() 方法用于接收一个指定的信号,

方法原型:

    def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
"""
receiver : 当前信号连接的回调函数,也就是处理信号的函数。
sender : 指定从哪个发送方接收信号。
weak : 是否弱引用
dispatch_uid :信号接收器的唯一标识符,以防信号多次发送。
"""

注意: 接收信号时 可不指定 信号的发送方 sender 参数,代表 此种信号 都 接收。

第二种 接收信号的 方式为使用 装饰器。 在处理信号的回调函数之上。此种方式内部 也是依次调用每个 信号实例的 connct() 方法 来接收。

方法原型

def receiver(signal, **kwargs):
def _decorator(func):
if isinstance(signal, (list, tuple)): # 第一个 参数 可为信号实例的 元组 或 列表
for s in signal:
s.connect(func, **kwargs)
else:
signal.connect(func, **kwargs)
return func
return _decorator

信号接收器

所谓 信号接收器 就是 接收到信号之后的触发动作, 一般为一个函数,

def signal_callback(sender, **kwargs):
print("is my callback")
"""
注意:所有的接收器都必须接收一个sender参数和一个**kwargs通配符参数
"""

防止重复信号

为了防止重复信号,可以设置dispatch_uid参数来标识你的接收器,标识符通常是一个字符串,如下所示

from django.core.signals import request_finished

request_finished.connect(my_callback, dispatch_uid="my_unique_identifier")

最后的结果是,对于每个唯一的dispatch_uid值,你的接收器都只绑定到信号一次

Django 内置信号操作步骤

from django.core.signals import request_finished # 导入 信号

request_finished.connect(callback_func)          # 接收 信号 , 并 指定 回调函数

自定义信号操作步骤

创建文件

Django 定义信号一般都存储于 app 目录下的 signals.py 文件中, 故首先在 app 目录下 创建一个 signals.py 文件

自定义信号

在 第一步定义的 signals.py 中:

from django.dispatch import Signal

suosuo_signal = Signal()

自定义信号接收器

可在任意位置, 一般 放置 与 和在 信号发送语句 同一个 文件中, 例如 视图文件 views.py 中

from django.dispatch import receiver

@receiver(signal=[suosuo_signal,], sender=SuoSuo)  # signal 必须指定,   sender  可选
def basket(sender, **kwargs): # 两个 参数必须 同样指定
print('Signal %s, callback func: basket '%sender.__name__)
print('SuoSuo 的 信号接收器')

自定义 信号发送语句

例如 在 views.py 中

from django.views import View
from django.http import HttpResponse, JsonResponse
from suosuo.signals import suosuo_signal class SuoSuo(View):
def get(self,request):
suosuo_signal.send(sender=self.__class__,)
return HttpResponse("SuoSuo is Good") def post(self, request):
suosuo_signal.send_robust(sender=self.__class__)
return JsonResponse({
"code": 200,
'msg': "is Successful",
})

Django 高级配置的更多相关文章

  1. Django高级部分

    Django高级部分 1.上传图片: 当Django在处理文件上传的时候,文件数据被保存在request.FILES,FILES中的每个键为<input type="file" ...

  2. 最优Django环境配置

    2 最优Django环境配置 本章描述了我们认为对于中等和高级Django使用者来说最优的本地环境配置 2.1 统一使用相同的数据库引擎 一个常见的开发者错误是在本地开发环境中使用SQLite3,而在 ...

  3. python 全栈开发,Day96(Django REST framework 视图,django logging配置,django-debug-toolbar使用指南)

    昨日内容回顾 1. Serializer(序列化) 1. ORM对应的query_set和ORM对象转换成JSON格式的数据 1. 在序列化类中定义自定义的字段:SerializerMethodFie ...

  4. Django - 常用配置

    一.logging配置 Django项目常用的logging配置 settings.py LOGGING = { 'version': 1, 'disable_existing_loggers': F ...

  5. Django高级实战 开发企业级问答网站 ✌✌

    Django高级实战 开发企业级问答网站 (一个人学习或许会很枯燥,但是寻找更多志同道合的朋友一起,学习将会变得更加有意义✌✌) 从实际需求分析开始,实现当今主流知识问答应用的功能,包括动态.文章.问 ...

  6. Django路由配置

    Django路由配置系统.视图函数 1.路由配置系统(URLconf) URL配置(URLconf)就像Django 所支撑网站的目录.它的本质是URL与要为该URL调用的视图函数之间的映射表:你就是 ...

  7. [Django高级之forms组件]

    [Django高级之forms组件] forms组件之校验字段 # 第一步:定义一个类,继承forms.Form # 第二步:在类中写字段,要校验的字段,字段属性就是校验规则 # 第三步:实例化得到一 ...

  8. [Django高级之Auth模块]

    [Django高级之Auth模块] auth模块 ←详情点击查看 1.Auth模块是什么 Auth模块是Django自带的用户认证模块: 我们在开发一个网站的时候,无可避免的需要设计实现网站的用户系统 ...

  9. django 高级扩展-中间件-上传图片-分页-富文本-celery

    """ django 高级扩展 一.静态文件 1.css,js,json,图片,字体等 2.配置setting,在最底下设置静态文件目录,写入下面代码 #配置静态文件目录 ...

随机推荐

  1. windows下zookeeper集群安装

    windows下zookeeper单机版安装,见:https://www.cnblogs.com/lbky/p/9867899.html 一:zookeeper节点为什么是奇数个? 单机模式的zk进程 ...

  2. orm中 如何模糊匹配某一年的用户和某一事时间段的用户

    导入Q查询

  3. Intel CPU编号详解

    一.概述 Intel(英特尔)是当前最主流的台式机.笔记本.服务器CPU厂商.和英特尔类似的还有AMD厂商的CPU. Intel生产的CPU型号繁多,每个型号的CPU都有对应的编号.这个编号有特定意义 ...

  4. (2)用C语言实现面向对象---封装、继承和多态

    封装:struct中封装成员变量和函数指针. 继承:结构体中嵌套结构体. 多态:子类对象动态指向父类的现象叫多态. void  pFunction2(void) { printf(“函数2”): } ...

  5. 20180910-Java 文档注释

    Java 文档注释 Java只是三种注释方式.前两种分别是// 和/* */,第三种被称作说明注释,它以/** 开始,以 */结束. // /* */ /** */ 说明注释允许你在程序中嵌入关于程序 ...

  6. Docker容器日常操作命令

    在Docker的运用中,从下载镜像,启动容器,在容器中输入命令来运行程序,这些命令都是手工一条条往里输入的,无法重复利用,而且效率很低.所以就需要一 种文件或脚本,我们把想执行的操作以命令的方式写入其 ...

  7. Mac下用命令行压缩和解压rar文件的方法

    废话不多说,直接进入主题 第一步:下载RAR工具包,根据自己需要下载相对应的版本 第二步:解压对应的压在的压缩包rarosx-5.4.0.tar.gz(我下载的是5.4.0版本) 第三步:从终端进入到 ...

  8. WCF身份验证之用户名密码认证

    WCF支持多种认证技术,例如Windowns认证.X509证书.Issued Tokens.用户名密码认证等,在跨Windows域分布的系统中,用户名密码认证是比较常用的,要实现用户名密码认证,就必须 ...

  9. 洛谷T89643 escape

    题目描述 题目链接:https://www.luogu.org/problem/T89643 由于 Kiana 实在是太忙了,所以今天的题里面没有 Kiana. 某一天学校里有 n 节课,出题人希望逃 ...

  10. simhash文本相似度比较

    simhash 在simhash中处理一个文本的步骤如下: 第一步,分词: 对文本进行分词操作,同时需要我们同时返回当前词组在文本内容中的权重(这基本上是目前所有分词工具都支持的功能). 第二步,计算 ...