深入理解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 相关文章推荐
Linux中安装Python的交互式解释器IPython的教程
Jun 13 Python
Python实现冒泡排序的简单应用示例
Dec 11 Python
Python 查找list中的某个元素的所有的下标方法
Jun 27 Python
python实现弹窗祝福效果
Apr 07 Python
Python Django 实现简单注册功能过程详解
Jul 29 Python
pytorch 共享参数的示例
Aug 17 Python
python groupby 函数 as_index详解
Dec 16 Python
使用PyQt5实现图片查看器的示例代码
Apr 21 Python
python实现数字炸弹游戏
Jul 17 Python
Django多个app urls配置代码实例
Nov 26 Python
Python趣味实战之手把手教你实现举牌小人生成器
Jun 07 Python
Python实现简单的俄罗斯方块游戏
Sep 25 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
无线电广播与收音机发展的历史回眸
2021/03/02 无线电
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
php中rename函数用法分析
2014/11/15 PHP
Laravel中间件实现原理详解
2016/10/09 PHP
微信公众号OAuth2.0网页授权问题浅析
2017/01/21 PHP
JavaScript 特殊字符
2007/04/05 Javascript
JavaScript 继承的实现
2009/07/09 Javascript
JavaScript中String和StringBuffer的速度之争
2010/04/01 Javascript
js对象之JS入门之Array对象操作小结
2011/01/09 Javascript
JS 操作Array数组的方法及属性实例解析
2014/01/08 Javascript
js实现九宫格图片半透明渐显特效的方法
2015/02/16 Javascript
jQuery实现多级联动下拉列表查询框
2016/01/18 Javascript
基于javascript实现tab选项卡切换特效调试笔记
2016/03/30 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
你知道setTimeout是如何运行的吗?
2016/08/16 Javascript
JSON与String互转的实现方法(Javascript)
2016/09/27 Javascript
layer弹出层框架alert与msg详解
2017/03/14 Javascript
浅析bootstrap原理及优缺点
2017/03/19 Javascript
Angular动态添加、删除输入框并计算值实例代码
2017/03/29 Javascript
vue2.0 子组件改变props值,并向父组件传值的方法
2018/03/01 Javascript
微信小程序实现折叠与展开文章功能
2018/06/12 Javascript
浅谈Angular6的服务和依赖注入
2018/06/27 Javascript
详解vue 兼容IE报错解决方案
2018/12/29 Javascript
JavaScript字符串转数字的简单实现方法
2020/11/27 Javascript
opencv实现简单人脸识别
2021/02/19 Python
python 如何将数据写入本地txt文本文件的实现方法
2019/09/11 Python
html5 Canvas实现图片旋转的示例
2018/01/15 HTML / CSS
军人违纪检讨书
2014/02/04 职场文书
认识深刻的检讨书
2014/02/16 职场文书
2014年小学植树节活动方案
2014/03/02 职场文书
创先争优承诺书范文
2014/03/31 职场文书
经济担保书范文
2014/04/02 职场文书
班子四风对照检查材料
2014/08/21 职场文书
小学生清明节演讲稿
2014/09/05 职场文书
乡镇干部学习心得体会
2016/01/23 职场文书
财务年终工作总结大全
2019/06/20 职场文书