• Django 信号机制


    信号机制

       Django提供信号机制,类似于在某些特定的流程中设置一系列的HookFunction

       具体概念一言以蔽之,用户发生某些动作后,会发送一个特定动作的信号,我们只需要为他设置回调函数即可。

       举个例子,现在项目中用到了MySQLRedis,当我们更新某张数据表记录时,希望Redis中也同时更新,这个时候就可以用到信号。

    Model

       在Model操作中,有以下一些信号提供:

    信号描述
    pre_init modal执行其构造方法前,自动触发
    post_init modal执行其构造方法后,自动触发
    pre_save modal对象保存前,自动触发
    post_save modal对象保存后,自动触发
    pre_delete modal对象删除前,自动触发
    post_delete modal对象删除后,自动触发
    m2m_changed modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
    connection_created 创建数据库链接时,自动触发
    pre_migrate 执行migrate命令前,自动触发
    post_migrate 执行migrate命令后,自动触发

       导入Model相关的信号:

    from django.db.models.signals import class_prepared
    from django.db.models.signals import pre_init, post_init
    from django.db.models.signals import pre_save, post_save
    from django.db.models.signals import pre_delete, post_delete
    from django.db.models.signals import m2m_changed
    from django.db.models.signals import pre_migrate, post_migrate
    

    Request/Response

       在请求和响应中,有下面的一些信号:

    信号描述
    request_started 请求到来前,自动触发
    request_finished 请求结束后,自动触发
    got_request_exception 求异常后,自动触发

       值得一提的是,request/response信号相比于中间件来说,并不具备拦截功能。

    from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception
    

    Test

       使用测试模式进行调试时,信号如下:

    信号描述
    setting_changed 使用test测试修改配置文件时,自动触发
    template_rendered 使用test测试渲染模板时,自动触发

       导入信号:

    from django.test.signals import setting_changed
    from django.test.signals import template_rendered
    

    DB

       在DB相关中,只有一个信号:

    信号描述
    connection_created 创建数据库连接时,自动触发

    使用信号

       只需要在项目全局文件夹下的__init__里注册信号即可,注册方式有两种:

    # 项目全局文件夹/__init__.py
    
    from django.dispatch import receiver
    from django.db.models.signals import post_save
    
    @receiver(post_save)
    def callback(sender,**kwargs):
        """
        :param sender: 本次操作的class
        :param kwargs: 参数
        :return: 
        """
        print(sender)
        print(kwargs)
    

       上面的注册方式更为推荐,或者你也可以使用比较笨的办法:

    # 项目全局文件夹/__init__.py
    from django.db.models.signals import post_save
    
    def callback(sender,**kwargs):
        """
        :param sender: 本次发送信号的信号源
        :param kwargs: 参数
        :return:
        """
        print(sender)
        print(kwargs)
    
    post_save.connect(callback)
    

       执行结果如下:

    """
    <class 'app01.models.User'>
    {'signal': <django.db.models.signals.ModelSignal object at 0x0000015230B6C2B0>, 'instance': <User: User object (3)>, 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}
    """
    

    自定义信号

       Django内置信号是在特定地点自动发送信号,我们只需要设置回调即可,但是如果是自定义信号则需要我们自己定义信号、发送信号、接收信号。

       首先创建一个py文件,用于存放创建的信号:

    # app01/common_signals.py
    
    import django.dispatch
    # 定义信号
    first_signal = django.dispatch.Signal(providing_args=['params_001', 'params_002'])
    

       然后需要设置回调该信号的函数:

    # 项目全局文件夹/__init__.py
    
    from app01.common_signals import first_signal
    from django.dispatch import receiver
    
    @receiver(first_signal)
    def callback(sender,**kwargs):
        """
        :param sender: 本次发送信号的信号源
        :param kwargs: 参数
        :return:
        """
        print(sender)
        print(kwargs)
    
    

       最后是使用信号:

    # app01/views.py
    
    from django.shortcuts import HttpResponse
    from .common_signals import first_signal
    
    import sys # 获取函数名
    
    def add(request):
        first_signal.send(sender=sys._getframe().f_code.co_name,params_001="参数1",params_002="参数2")
        return HttpResponse("ok")
    

       执行结果如下:

    """
    add
    {'signal': <django.dispatch.dispatcher.Signal object at 0x000001F3508E9710>, 'params_001': '参数1', 'params_002': '参数2'}
    """
    
  • 相关阅读:
    字符串形式导入模块
    pycharm 远程环境开发调试
    ubuntu 18.04 及初始化python3环境
    nbu备份虚拟机
    转载
    linux/centos/rhel同时安装oracle10g和11g
    多进程
    drf笔记
    单例模式
    常用模块
  • 原文地址:https://www.cnblogs.com/Yunya-Cnblogs/p/14279742.html
Copyright © 2020-2023  润新知