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. [LeetCode] 53. Maximum Subarray 最大子数组 --动态规划+分治

    Given an integer array nums, find the contiguous subarray (containing at least one number) which has ...

  2. OC + RAC(七) RACSubject和RACSignal的区别

    -(void)_test8{ /// RACSubject继承自RACSignal 但是RACSubject和RACSignal的区别? //1能接收1,2 //但是2只能接收2 RACSubject ...

  3. Http发送Json

    public static JSONObject post(String url,JSONObject json){ HttpClient client = new DefaultHttpClient ...

  4. ionic学习使用笔记(二) slide 组件的使用

    开始做的时候,遇到了个要用ionic实现 有一系列的序列需要展示,但是当前页面上只能展示一小部分,剩余的在没有出现时是隐藏的,还得能滑动出现,但是又不能有滚动条. 之前使用jQuery来实现的话,其实 ...

  5. LintCode之两两交换链表中的节点

    题目描述: 我的思路: 由题目描述可知,题目是要求将第一个与第二个节点,第三个与第四节点....进行交换,而进行交换时只用将节点的值进行交换即可.需要注意的是:当链表为null或者当链表只有一个节点时 ...

  6. php面试专题---12、JavaScript和jQuery基础考点

    php面试专题---12.JavaScript和jQuery基础考点 一.总结 一句话总结: 比较常考察的是JavaScript的HTML样式操作以及jQuery的选择器和事件.样式操作. 1.下列不 ...

  7. 《图解设计模式》读书笔记3-3 Builder模式

    目录 示例程序 类图 代码 角色 思路拓展 谁知道什么 构造和实现分离 和Template Method模式的区别和联系? Builder模式即建造者模式,利用这个模式可以组装具有复杂结构的实例. 示 ...

  8. Vagrant 入门 - 清理(teardown)

    原文地址 我们现在有一个功能齐全的虚拟机,可以用于基本 Web 开发.但如果现在需要更换设备,或者在另一个项目上工作,如何清理我们的开发环境? 借助 Vagrant,可以暂停(suspend),停止( ...

  9. javaScript Map

                  }                   } }                          vertices.push(v);         adjList.set ...

  10. [Linux] 004 安装

    1. 安装欢迎界面 Install or upgrade an existing system 安装或升级现有系统 Install system with basic video driver 安装过 ...