django signal

Django中信号signal针对model的使用 Django中实现对数据库操作的记录除了使用开源插件还可以使用信号signal独立实现 信号机制-观察者模式-发布与订阅:signal 配置 # 文件路径:Django/myapps/__init__.py default_app_config = 'myapps.apps.MyAppsConfig' # 文件路径:Django/myapps/apps.py from django.apps import AppConfig class MyAppsConfig(AppConfig): nam 阅读详情

django拾遗之signal

摘要

突然发现自己比较喜欢写系列类型的文章, 因为通常类似的一些文章都具有相同的特征,但 一篇很难完全覆盖,所以往往写系列的文章比较合适.

拾遗 系列的文章主要是一些 常被程序员忽略, 但 又特别有意义 的一些内容.

引入

在web开发中, 你可能会遇到下面这种场景:

在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后,
你要发送一份确认邮件.

当然你可以把逻辑写在一起, 但是有个问题是, 通常前置动作(触发操作)会不止一种(如用户更改了其它信息的确认邮件), 这时候这个逻辑会需要写多次, 所以你可能会想着DRY, 于是你把它写到了一个函数中,每次调用. 当然这是没问题的.

但是, 如果你换个思路你会发现另一个完全不同的方案, 即:

  1. 类似于daemon的程序监听着特定的事件
  2. 前置操作来触发相应的事件
  3. 监听程序执行对应的操作

这样的好处是什么呢?

  1. 松耦合(不用把后续操作写在主逻辑中)
  2. 便于复用(这也是为什么 django 本身, 及第三方应用如 pinax 大量使用此技术的原因)

在各种高级语言中都会有类似的特性,如java, javascript等.而在 django 中我们使用 signal.

本文会着重介绍 django 的 signal 相关知识.

django的signal定义

什么是signal?

django 包含一个称为 signal dispatcher, 用来解耦合框架中发生的事件与 得到通知的应用 之间的逻辑. 简单地说, 在特定事件发生时, 使用signal 发送者 能够通知一系列 接收者(一个或者多个).

python 本身没有类似机制的支持, 但是 django 基于 PyDispatcher 进行了性能 和代码结构上的优化来增加了signal功能.

如何使用django的signal

在使用signal之前,我们先了解下django signal的处理流程.

参考下图:

http://farm3.static.flickr.com/2468/4048888885_23bf82c838_o.png

那么我们来逐步完成我们简单的signal.

场景

我们有2个页面 ,一个是文章显示页面,一个是文章增加页面, 文章只有title,content及is_public三个域.

我们使用signal是完成,当用户添加一个文章后,我们置其is_public=False, 我们使用signal来实现此功能.

注册signal

下面是测试用的project的文件结构,具体可以 下载源代码 来在本地运行.

.
|-- __init__.py
|-- __init__.pyc
|-- logs
| `-- filelog.log
|-- manage.py
|-- settings.py
|-- settings.pyc
|-- signal.db
|-- testsignal
| |-- __init__.py
| |-- __init__.pyc
| |-- models.py
| |-- models.pyc
| |-- signals.py
| |-- signals.pyc
| |-- templates
| | |-- add.html
| | |-- base.html
| | `-- index.html
| |-- tests.py
| |-- urls.py
| |-- urls.pyc
| |-- views.py
| `-- views.pyc
|-- urls.py
`-- urls.pyc

testsignal是我们建立的示例app, 我们首先要注册signal, 具体代码如下(testsignal/signals.py):

import django.dispatch
    delete_done = django.dispatch.Signal(providing_args=['obj'])

引入django的包, 并且注册 delete_done为我们将要使用的signal.

关联signal对应的listener

然后我们关联对应的listener, 代码如下: (testsignal/models.py)

from django.db.models.signals import pre_save
from django.db import models
import logging
import signals
# Create your models here.
class Article(models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    is_public = models.BooleanField(default=True, blank=True)
    def delete(self):
        #self.is_public = False
        signals.delete_done.send(sender=Article, obj=self)
    def __unicode__(self):
        return self.title
    def zhutao(sender, kwargs):
         logging.debug(kwargs)
        if "obj" in kwargs:
             obj = kwargs.get("obj")
             logging.debug(obj.is_public)
             obj.is_public = False
             obj.save()
             logging.debug("signal recieved! zhutao is called.")
             logging.debug(obj.is_public)
signals.delete_done.connect(zhutao, sender=Article)

我们来看最后一行, signals.delete_done.connect(zhutao, sender=Article), 即将 我们上面注册的 delete_done 和 监听函数 zhutao 关联了起来, 而 这里的 sender=Article, 则是用来限制只有当Article有更新时我们才会触发这个事件.

触发监听事件

最后,我们要在特定操作发生时触发相应的监听函数, 具体代码如下(testsignal/views.py):

from django.http import HttpResponse,HttpResponseRedirect
from django.core.urlresolvers import reverse
from django.shortcuts import render_to_response
import signals
from models import *
def index(request):
    articles = Article.objects.all().order_by("-id")
    return render_to_response("index.html", {"articles":articles})

def add(request):
    if request.method == "POST":
        title = request.POST.get("title", "")
        content = request.POST.get("content", "")
    if title and content:
        article = Article(title=title, content=content)
        article.save()
        article.delete()
       return HttpResponseRedirect(reverse(index))

    return render_to_response("add.html", {})

其它的只是django的普通views.py中的方法,我们主要来看 article.delete() 这行代码, 执行这个后,我们会调用models.py中的delete方法,见上面的models.py中的代码, 它会执行下面一行代码:

signals.delete_done.send(sender=Article, obj=self)

面这行代码正是向delete_done发送了事件的触发,此时,对应的监听函数 zhutao 会得到执行,

从而将 is_public 置为False.

我们的任务也得以完成.

具体的说明可以 下载源代码 来运行,你会在logs/filelog.log文件中看到对应的log输出.

示例输出为:

2009-10-27 03:28:27,202 DEBUG models.zhutao Line:26 {'signal': <django.dispatch.dispatcher.Signal object at 0x9523e4c>, 'obj': <Article: aaa>}
2009-10-27 03:28:27,203 DEBUG models.zhutao Line:29 True
2009-10-27 03:28:27,209 DEBUG models.zhutao Line:32 signal recieved! zhutao is called.
2009-10-27 03:28:27,209 DEBUG models.zhutao Line:33 False

一些其它的应用

我们上面提到过 django, pinax 也大量地使用了signal技术,那我们下面简要看看, django 中有哪些具体的应用.

在 django 中, 主要有下面几类:

  1. Model signals

    • pre_init
    • post_init
    • pre_save
    • post_save
    • pre_delete
    • post_delete
    • class_prepared
  2. Management signals

    • post_syncdb
  3. Request/response signals

    • request_started
    • request_finished
    • got_request_exception
  4. Test signals

    • template_rendered

这些都是 django 内置的signals来方便用户来进行一些特定的操作,具体的介绍可以参考: built-in signals.

至于 pinax 可以下载其源代码来具体查看.

可能的应用场景

那么signals有哪些可能的应用场景呢?我们能够在什么样的场景下使用呢?

从定义来看,其实已经很明确了, 如果一个操作可能会触发多个后续事件, 此时使用signals会非常方便.

那么具体的应用可以考虑:

  1. sns中的事件通知, 如用户发表了一篇博文, 然后通知所有的好友
  2. 用户信息的更改的邮件通知
  3. 用户订制信息的邮件通知等

结论

django 的signals是非常强大的, 如果我们能够很好地使用,则能够大大地提高代码的可维护性, 复用性,以及减少耦合等.

深入理解Django-Signals信号量 主要介绍了深入理解Django-Signals信号量,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧 立即下载

相关推荐

浅谈优化Django ORM中的性能问题

主要介绍了浅谈优化Django ORM中的性能问题,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

Django—信号 signal_django signal例子

除了Django为我们提供的内置信号(比如前面列举的那些),很多时候,我们需要自己定义信号。所有的信号都是的实例。print(“我已经做完了工作。现在我发送一个信号出去,给那些指定的接收器。”)自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

2401_84247341的博客 1247

Windows 11 24H2 外接显卡坞兼容性实测:3步解决USB设备失效

本文详细解析了Windows 11 24H2系统下外接显卡坞导致USB设备失效的问题,并提供了三步终极解决方案:驱动预解压与手动更新、电源管理设置调整、优化的设备连接顺序。通过雷电3接口的兼容性优化,帮助用户解决键盘鼠标卡死等常见问题,提升外接显卡坞的稳定性与性能。

weixin_31714129的博客 593

django的信号signals详解

django的信号signals详解

python_web全栈 4018

JW01二氧化碳传感器实战:5分钟搞定Arduino环境监测系统(附完整代码)

本文详细介绍了如何使用JW01二氧化碳传感器与Arduino快速搭建环境监测系统。通过简单的硬件连接和完整的代码示例,读者可以在5分钟内实现CO2浓度实时监测,并了解数据解析、常见问题解决及进阶应用扩展。JW01传感器的高精度和易用性使其成为创客和嵌入式开发者的理想选择。

kite3的博客 383

从开通VPS到搭建宝塔面板全教程

你在输入域名(此时我们可能没有类似aaa.com这样的域名,所以要输入VPS的IP地址)的时候,下面的根目录也会跟着变动,等输入完成后,你可以把根目录再改回成/www/wwwroot/dq。这时,在你的浏览器中,输入外网面板地址的URL,输入username和password,即可登陆宝塔面板。第一次登陆,需要绑定你的宝塔账号,你可以到宝塔的注册界面,用手机注册一个,然后绑定,首先看一下你的VPS操作系统是什么类型的(其实你在选择VPS的时候,就已经选定了,我选择的事Centos系统)。

kxltsuperr的专栏 3734

django的信号量

django的信号量 一、关于django信号量官网单位 Django包含一个"信号调度程序",它有助于在框架中的其他位置发生操作时通知分离的应用程序。简而言之,信号允许某些发送者通知一组接收器已经发生了某些动作。当许多代码可能对同一事件感兴趣时,它们特别有用. 二、django中内置的信号量 1、Model的信号量 pre_init # djan...

weixin_34220179的博客 617

ROS水下仿真神器uuv_simulator:从零搭建水下机器人测试环境(附Gazebo配置全流程)

本文详细介绍了如何使用ROS和uuv_simulator从零搭建水下机器人仿真测试环境,包括Gazebo配置全流程。通过系统环境准备、水下世界构建、机器人模型定制开发等步骤,帮助开发者在虚拟海洋环境中高效验证算法,大幅降低研发成本。特别适合水下机器人研发人员参考。

ujm5678901的博客 263

Django——信号量

django的某些操作发生时,会发出signals,可以截获signals,并进行一些操作 下面代码是在创建新用户完成时,截获signals,把保存的明文密码修改为密文   此app下创建signals.py 文件   from django.db.models.signals import post_save from django.dispatch import receiver f...

hllyzms的博客 2692

万物皆可GAN ---普通GAN, pix2pix, CycleGAN和pix2pixHD的比较以及演变过程

普通GAN, pix2pix, CycleGAN和pix2pixHD的原理、比较以及演变过程

m0_61985580的博客 3724

ADBMS1818芯片

 可测量多达18串电池电压 3 mV最大总测量误差 内置isoSPI接口 使用单根双绞线,长达100米 290 μs内可完成系统中所有单体电池电压测量。

m0_61973119的博客 4274

浅谈Django中的Signal

前言在web开发中, 你可能会遇到下面这种场景: 在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后, 你要发送一份确认邮件. 当然可以把逻辑写在一起,但是有个问题是,触发操作一般不止一种(如用户更改了其它信息的确认邮件),这时候这个逻辑会需要写多次,所以你可能会想着DRY(Don’t repeat yourself),于是你把它写到了一个函数中,每次调用。当然这是

Mr.Phoebe的专栏 3467

PyTorch深度学习项目实战100例数据集

最近很多订阅了的用户私信咨询有些数据集下载不了以及一些文章中没有给出数据集链接,为了解决这个问题,专门开设了本篇文章,提供数据集下载链接,打包100例的所有数据集。本专栏适用人群:深度学习初学者,专栏将具体讲解如何快速搭建深度学习模型用自己的数据集实现深度学习小项目。 本专栏整理了《PyTorch深度学习项目实战100例》,内包含了各种不同的深度学习项目,包含项目原理以及源码,每一个项目实例都附带有完整的代码+数据集。

优快云 精品推荐 2万+

Django Signal简析——从Observer Pattern到Django Signal

Django Signal 简析观察者模式Signal简述1. signal2. sender3. receiver原理简析1. Signal的属性和\__init__方法2. Signal中的方法3. 大概流程4. 很奇怪的一点5. 多说一句源码简析一些可能有用的链接 其实原本准备起名儿叫"Django Signal源码解析 ——从观察者模式到Django Signal"的,但是这样写实在太多了哈哈哈哈哈哈,写了一半实在写不动了就放弃了,重写了这篇 观察者模式 “观察者模式是一种对象行为模式。它定义对

heaciy的博客 413

11、基于STM32的智能药盒

当今时代是一个新技术层出不穷的时代,在电子领域尤其是自动化智能控制领域,传统的分立元件或数字逻辑电路构成的控制系统,正以前所未有的速度被单片机智能控制系统所取代。嵌入式具有体积小、功能强、成本低、应用面广等优点,可以说,智能控制与自动控制的核心就是单片机。

行走的皮卡丘 6103

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

django signal 拾遗

首先看看Signal类的一些主要的接口。 classSignal(object): def__init__(self,providing_args=None,use_caching=False): ...... defconnect...

chuiyan0987的博客 155

Outlook Express 6 (OE6) for Win7/Win8/Win10

英文版 Outlook Express6.0, 兼容Win7/Win10/WinXP,解压就可用。

Django Signal 解析

Siganl 是 Django 框架中提供的一个 “信号分发器”,其实就是设计模式中经常提到的 观察者模式的一个实现应用。Django 中Siganl 机制的典型应用是,框架为 Models 创建了 pre_save post_save等 与模型的某些方法调用相关联的信号,如 pre_save 和 post_save 分别 会在 Modle 的 save()方法的调用之前和之后 通知观察者。Sig

Knight-ZXW的博客 4658

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

django拾遗之signal

引入 在web开发中, 你可能会遇到下面这种场景: 在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后, 你要发送一份确认邮件. 当然你可以把逻辑写在一起, 但是有个问题是, 通常前置动作(触发操作)会不止一种(如用户更改了其它信息的确认邮件), 这时候这个逻辑会需要写多次, 所以你可能会想着DRY, 于是你把它写到了一个函数中,每次调用. 当然这是没问题的

筑梦★逐梦 959

django signal 使用总结

什么是django的signal 官方文档描述如下: Django includes a “signal dispatcher” which helps allow decoupled applications get notified when actions occur elsewhere in the framework.In a nutshell, signals allow cer...

a289237642的博客 573

Django系列---Signal信号

一.Signal的作用 了解数据库的朋友们都知道触发器(Tragger),可以理解为通过某一个条件触发另一个事件的发生,使用场景十分广泛。比如在电子商城项目中,在增加一个商品的时候,需要把这个增加商品的消息通知给每个店铺的关注者。当然,在POST视图增加商品的代码后面,加上通知的函数就可以完成这个需求。但是如果这个时候增加一个新需求,在更新商品的时候也需要通知店铺的关注者,这个时候怎么实现更加优雅呢? 二.Signal详解 Django框架的信号机制充斥在各个操作环节中,有多...

zyz930929的博客 643

利用Django的Signal 实现数据库初始化

前段时间遇到需要在数据库中初始化约2k个model实例用于实现类似邀请码的功能,发现使用Django提供的signal很是好用,对于这种应用,使用post_syncdb很容易实现。当然还有其他的方法可用,这里主要通过这个实例来讲Django的signal实现。 Signal简介 django 包含一个称为 signal dispatcher, 使得框架内其他松耦合或不相关的...

215

djangochannelsrestframework @observer 信号订阅:把 Django Signal 变成 WebSocket 实时通知

djangochannelsrestframework(简称 DCRF)是一个基于 Django Channels v4 的 WebSocket REST 框架,而 @observer 是它最具魅力的功能之一:只需几行代码,就能把 Django Signal 信号订阅变成实时推送的 WebSocket 通知。本文面向新手,用通俗的方式讲清 djangochannelsrestframework 信

gitblog_01089的博客 654

Django Signal 源码解析

Siganl 是 Django 框架中提供的一个 “信号分发器”,其实就是设计模式中经常提到的 观察者模式的一个实现应用。Django 中Siganl 机制的典型应用是,框架为 Models 创建了 pre_save post_save等 与模型的某些方法调用相关联的信号,如 pre_save 和 post_save 分别 会在 Modle 的 save()方法的调用之前和之后 通知观察者。

nicajonh的博客 527

[转]django拾遗之signal

在web开发中, 你可能会遇到下面这种场景: 在用户完成某个操作后, 自动去执行一些后续的操作. 譬如用户完成修改密码后,你要发送一份确认邮件.当然你可以把逻辑写在一起, 但是有个问题是, 通常前置动作(触发操作)会不止一种(如用户更改了其它信息的确认邮件), 这时候这个逻辑会需要写多次, 所以你可能会想着DRY, 于是你把它写到了一个函数中,每次调用. 当然这是没问题的.但是, 如果你换个思路...

麻烦处... 214
上一篇: python垃圾回收机制
下一篇: django signal基础
youbo_sun
博客等级 码龄12年 20粉丝 51原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值