深入理解Django自定义信号(signals)


Posted in Python onOctober 15, 2018

django中自定义了一些singals,用于监听一些操作,并发出通知

官方解释:

Django 提供一个“信号分发器”,允许解耦的应用在框架的其它地方发生操作时会被通知到。

简单来说,信号允许特定的sender通知一组receiver某些操作已经发生。这在多处代码和同一事件有关联的情况下很有用。
django中已经内置了一些singals,在django/db/models/signal.py中,如

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     # 创建数据库连接时,自动触发

用法:

利用这几个singals可以实现model中的一些联动操作,比如,要想更改通过model更新记录时,记下操作者的日志,可以直接在操作的地方使用post_save装饰器,

或者改写post_save,使其记录相关信息,一劳永逸。或者在request请求时,记录请求信息。

from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs):
  print("Request finished!")

如何自定义singals?

a. 定义singal文件

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

b. 注册singal

def callback(sender, **kwargs):
  print("callback")
  print(sender,kwargs)
  pizza_done.connect(callback)

c. 触发信号

from 路径 import pizza_done
pizza_done.send(sender='seven',toppings=123, size=456)

需求场景:

项目中有一个需求,当model(即库的数据)被修改或者删除时,自动触发一个redis的同步任务(后来发现这个需求没有意义....),model的保存有post_save,删除有post_delete,唯独没有update,而代码中使用update的场景蛮多的,就搜了下为什么就是没有update的singals。

看到:https://code.djangoproject.com/ticket/12184

其实很早就有人给django官方提过这种方式,为什么不在官方版本中添加,具体这个pr为什么没有被接受,可以看下里面的讨论,反正当时的django1.9仍然不支持,只能自己先写一个用用,有问题了再撤掉好了。

解决方式:

singals.py文件

# coding:utf-8
from django.dispatch import Signal
post_update = Signal(providing_args=["user"])

models.py文件

-----------针对某个model,重写其queryset中的update方法-----------

//引入自定义的signal文件
from tools import signals 

class MyCustomQuerySet(models.query.QuerySet):
  def update(self, **kwargs):
    super(MyCustomQuerySet, self).update(**kwargs)
    //update被调用时, 发送该singalsignals
    signals.post_update.send(sender=self.model, user="xxx")
    print("finished!")

class MyCustomManager(models.Manager):
  def get_queryset(self):
    return MyCustomQuerySet(self.model, using=self._db)

class crontab_ping(models.Model):
  name = models.CharField(max_length=64, blank=True, null=True)
  objects = MyCustomManager()

callback.py文件:

-------接收signal,触发操作----------

from tools.signals import post_update

@receiver(post_update)
def post_update_callback(sender, **kwargs):
  print(kwargs['user'])
  print("post_update_success")

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中使用hashlib模块处理算法的教程
Apr 28 Python
python+ffmpeg批量去视频开头的方法
Jan 09 Python
Python socket实现多对多全双工通信的方法
Feb 13 Python
Django框架自定义模型管理器与元选项用法分析
Jul 22 Python
Python操作SQLite数据库过程解析
Sep 02 Python
使用Python刷淘宝喵币(低阶入门版)
Oct 30 Python
python使用多线程+socket实现端口扫描
May 28 Python
详解Python 中的容器 collections
Aug 17 Python
python 调用Google翻译接口的方法
Dec 09 Python
SpringBoot首页设置解析(推荐)
Feb 11 Python
python实现图片批量压缩
Apr 24 Python
python 安全地删除列表元素的方法
Mar 16 Python
使用numba对Python运算加速的方法
Oct 15 #Python
浅谈解除装饰器作用(python3新增)
Oct 15 #Python
python  创建一个保留重复值的列表的补码
Oct 15 #Python
python 美化输出信息的实例
Oct 15 #Python
python  Django中的apps.py的目的是什么
Oct 15 #Python
使用Python监视指定目录下文件变更的方法
Oct 15 #Python
Python调用adb命令实现对多台设备同时进行reboot的方法
Oct 15 #Python
You might like
PHP中一个控制字符串输出的函数
2006/10/09 PHP
PHP中json_encode、json_decode与serialize、unserialize的性能测试分析
2010/06/09 PHP
PHP实现的汉字拼音转换和公历农历转换类及使用示例
2014/07/01 PHP
PHP实现生成唯一会员卡号
2015/08/24 PHP
php的mail函数发送UTF-8编码中文邮件时标题乱码的解决办法
2015/10/20 PHP
浅析PHP数据导出知识点
2018/02/17 PHP
Laravel 自定命令以及生成文件的例子
2019/10/23 PHP
jQuery获取Radio,CheckBox选择的Value值(示例代码)
2013/12/12 Javascript
详谈javascript中的cookie
2015/06/03 Javascript
ES6新特性八:async函数用法实例详解
2017/04/21 Javascript
深究AngularJS之ui-router详解
2017/06/13 Javascript
vue中实现在外部调用methods的方法(推荐)
2018/02/08 Javascript
详解vue2.0+vue-video-player实现hls播放全过程
2018/03/02 Javascript
vue+axios新手实践实现登陆的示例代码
2018/06/06 Javascript
解决vue项目打包后提示图片文件路径错误的问题
2018/07/04 Javascript
nodejs基础之buffer缓冲区用法分析
2018/12/26 NodeJs
js继承的这6种方式!(上)
2019/04/23 Javascript
详解在Javascript中进行面向切面编程
2019/04/28 Javascript
Vue Element校验validate的实例
2020/09/21 Javascript
vue项目中企业微信使用js-sdk时config和agentConfig配置方式详解
2020/12/15 Vue.js
python IDLE 背景以及字体大小的修改方法
2019/07/12 Python
Win下PyInstaller 安装和使用教程
2019/12/25 Python
python encrypt 实现AES加密的实例详解
2020/02/20 Python
Python实现在Windows平台修改文件属性
2020/03/05 Python
如何理解Python中包的引入
2020/05/29 Python
python 多线程中join()的作用
2020/10/29 Python
浅析数据存储的三种方式 cookie sessionstorage localstorage 的异同
2020/06/04 HTML / CSS
英国最大的自有市场,比亚马逊便宜:Flubit
2019/03/19 全球购物
红色故事演讲稿
2014/05/22 职场文书
英语教师自荐信
2014/05/26 职场文书
2015年外联部工作总结
2015/04/03 职场文书
教师创先争优承诺书
2015/04/27 职场文书
2019行政前台转正申请书范文3篇
2019/08/15 职场文书
读《方与圆》有感:交友方圆有度
2020/01/14 职场文书
25句企业管理语录:助你迅速打开思路,句句经典!
2020/01/14 职场文书
拙作再改《我的收音机情缘》
2022/04/05 无线电