深入理解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 相关文章推荐
利用arcgis的python读取要素的X,Y方法
Dec 22 Python
PyQt5实现类似别踩白块游戏
Jan 24 Python
python tkinter实现界面切换的示例代码
Jun 14 Python
Flask框架模板继承实现方法分析
Jul 31 Python
Python 2种方法求某个范围内的所有素数(质数)
Jan 31 Python
Python调用Windows命令打印文件
Feb 07 Python
Python BeautifulReport可视化报告代码实例
Apr 13 Python
Python3自定义json逐层解析器代码
May 11 Python
Python logging日志模块 配置文件方式
Jul 12 Python
Python基于execjs运行js过程解析
Nov 27 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
Feb 07 Python
pytorch 实现变分自动编码器的操作
May 24 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
类的另类用法--数据的封装
2006/10/09 PHP
php实现的替换敏感字符串类实例
2014/09/22 PHP
跟我学Laravel之视图 & Response
2014/10/15 PHP
PHP可变函数学习小结
2015/11/29 PHP
PHP处理数组和XML之间的互相转换
2016/06/02 PHP
PHP与Java对比学习日期时间函数
2016/07/03 PHP
js简单实现根据身份证号码识别性别年龄生日
2013/11/29 Javascript
node.js中的fs.writeFileSync方法使用说明
2014/12/14 Javascript
测试IE浏览器对JavaScript的AngularJS的兼容性
2015/06/19 Javascript
JavaScript包装对象使用详解
2015/07/09 Javascript
老生常谈js动态添加事件--- 事件委托
2016/07/19 Javascript
如何用js判断dom是否有存在某class的值
2017/02/13 Javascript
Angular.js自定义指令学习笔记实例
2017/02/24 Javascript
jQuery为某个div加入行样式
2017/06/09 jQuery
JavaScript html5 canvas实现图片上画超链接
2017/10/20 Javascript
微信小程序实现聊天对话(文本、图片)功能
2018/07/06 Javascript
jQuery属性选择器用法实例分析
2019/06/28 jQuery
浅谈VUE中演示v-for为什么要加key
2020/01/16 Javascript
Python使用PyGreSQL操作PostgreSQL数据库教程
2014/07/30 Python
运动检测ViBe算法python实现代码
2018/01/09 Python
Python函数的参数常见分类与用法实例详解
2019/03/30 Python
python3.7简单的爬虫实例详解
2019/07/08 Python
tensorflow入门:tfrecord 和tf.data.TFRecordDataset的使用
2020/01/20 Python
pycharm远程连接服务器并配置python interpreter的方法
2020/12/23 Python
CSS3的常见transformation图形变化用法小结
2016/05/13 HTML / CSS
Canvas图片分割效果的实现
2019/07/29 HTML / CSS
三方合作协议书范本
2014/04/18 职场文书
三年级评语大全
2014/04/23 职场文书
环境保护建议书
2014/08/26 职场文书
先进事迹材料范文
2014/12/29 职场文书
导游词开场白
2015/01/31 职场文书
集团财务总监岗位职责
2015/04/03 职场文书
高三毕业感言
2015/07/30 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
导游词之泰山玉皇顶
2019/12/23 职场文书
什么是clearfix (一文搞清楚css清除浮动clearfix)
2023/05/21 HTML / CSS