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

 更新时间:2018年10月15日 11:31:15   作者:二二向箔  
这篇文章主要介绍了深入理解Django自定义信号(signals),小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧

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 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等)

    这篇文章主要介绍了Python 字符串操作(string替换、删除、截取、复制、连接、比较、查找、包含、大小写转换、分割等),需要的朋友可以参考下
    2018-03-03
  • python3的输入方式及多组输入方法

    python3的输入方式及多组输入方法

    今天小编就为大家分享一篇python3的输入方式及多组输入方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-10-10
  • 使用Python字典实现词频统计的方法

    使用Python字典实现词频统计的方法

    在Python中,利用字典进行词频统计是一种常见且强大的方式,通过对文本进行预处理并使用字典数据结构,可以轻松地统计文本中每个单词出现的频率,下面将详细解释这个过程,并提供多种例子,以帮助你更好地理解并应用这一技术,需要的朋友可以参考下
    2023-12-12
  • 使用django自带的user做外键的方法

    使用django自带的user做外键的方法

    这篇文章主要介绍了使用django自带的user做外键的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • Python中排序函数sorted()函数的使用实例

    Python中排序函数sorted()函数的使用实例

    sorted()作为Python内置函数之一,其功能是对序列(列表、元组、字典、集合、还包括字符串)进行排序,下面这篇文章主要给大家介绍了关于Python中排序函数sorted()函数的相关资料,需要的朋友可以参考下
    2022-11-11
  • 使用python绘制二维图形示例

    使用python绘制二维图形示例

    今天小编就为大家分享一篇使用python绘制二维图形示例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2019-11-11
  • Python中查看文件名和文件路径

    Python中查看文件名和文件路径

    本篇文章主要介绍了Python中查看文件名和文件路径的方法。具有很好的参考价值,下面跟着小编一起来看下吧
    2017-03-03
  • OpenCV中resize函数插值算法的实现过程(五种)

    OpenCV中resize函数插值算法的实现过程(五种)

    最新版OpenCV2.4.7中,cv::resize函数有五种插值算法:最近邻、双线性、双三次、基于像素区域关系、兰索斯插值。感兴趣的可以了解一下
    2021-06-06
  • 基于matplotlib+tkinter实现简单的绘图系统

    基于matplotlib+tkinter实现简单的绘图系统

    在理解matplotlib嵌入到tkinter中的原理之后,就已经具备了打造绘图系统的技术基础,所以本文来实现一个简单的绘图系统,感兴趣的小伙伴小伙伴可以了解一下
    2023-08-08
  • PyQt5 QFrame控件的用法详解

    PyQt5 QFrame控件的用法详解

    在PyQt5中,QFrame是一个重要的基类,它提供了边框样式、阴影效果、形状等属性,可以帮助开发者实现丰富多彩的界面效果,本文将结合实际案例,详细介绍QFrame在PyQt5中的用法,需要的朋友可以参考下
    2024-08-08

最新评论