zoukankan      html  css  js  c++  java
  • django 内置“信号”机制和自定义方法


    一、引子

      在操作数据的时候,假设我们需要记录一些日志,这个时候,我们需要用什么来显示这个需求呢?装饰器?装饰器只能先实现整体的操作。在django 里面有这么一个东西--信号 下面我们就来了解了解它。

      操作对象前后,django都会预留两个钩子,它是用signals.post_save.send,表示触发一个信号。所以比如说我们在操作数据库的时候,要在插入数据之前写入日志,插入完成之后也写入日志,那这个就会用到我们今天的django信号。Django中提供了“信号调度”,用于在框架执行操作时解耦。通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者。

    二、django的内置信号

      

    复制代码
     1 Model signals
     2     pre_init                    # django的modal执行其构造方法前,自动触发
     3     post_init                   # django的modal执行其构造方法后,自动触发
     4     pre_save                    # django的modal对象保存前,自动触发
     5     post_save                   # django的modal对象保存后,自动触发
     6     pre_delete                  # django的modal对象删除前,自动触发
     7     post_delete                 # django的modal对象删除后,自动触发
     8     m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
     9     class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
    10 Management signals
    11     pre_migrate                 # 执行migrate命令前,自动触发
    12     post_migrate                # 执行migrate命令后,自动触发
    13 Request/response signals
    14     request_started             # 请求到来前,自动触发
    15     request_finished            # 请求结束后,自动触发
    16     got_request_exception       # 请求异常后,自动触发
    17 Test signals
    18     setting_changed             # 使用test测试修改配置文件时,自动触发
    19     template_rendered           # 使用test测试渲染模板时,自动触发
    20 Database Wrappers
    21     connection_created          # 创建数据库连接时,自动触发
    复制代码

      对于Django内置的信号,仅需注册指定信号,当程序执行相应操作时,自动触发注册函数:

    复制代码
     1 import win_unicode_console
     2 win_unicode_console.enable()#这个在windows里面用的,这个需要用之前先安装一下
     3 from django.core.signals import request_finished
     4 from django.core.signals import request_started
     5 from django.core.signals import got_request_exception
     6  
     7 from django.db.models.signals import class_prepared
     8 from django.db.models.signals import pre_init, post_init
     9 from django.db.models.signals import pre_save, post_save
    10 from django.db.models.signals import pre_delete, post_delete
    11 from django.db.models.signals import m2m_changed
    12 from django.db.models.signals import pre_migrate, post_migrate
    13  
    14 from django.test.signals import setting_changed
    15 from django.test.signals import template_rendered
    16  
    17 from django.db.backends.signals import connection_created
    18  
    19 #这个函数你想写什么写什么,这边的注册函数可以写多个
    20 def callback(sender, **kwargs):
    21       print("xxoo_callback")
    22       print(sender,kwargs)
    23  
    24 xxoo.connect(callback)  #注册函数
    25 # xxoo指上述导入的内容,比如pre_init.connect(callback)
    复制代码

      注意了:当程序执行操作时,会自动触发注册函数,但是,不是随便放的,需要放在 project下的__init__.py文件中,这样的话,项目启动,文件内容就会自动加载到内存中,这样我们就可以方便使用了:

      

    三、搞一搞,测试一把

      3.1 models 创建数据库

    1
    2
    class User(models.Model):
        user=models.CharField(max_length=32)<br><br>执行:<code class="python plain hljs">python  manage.py makemigrations</code>
       python  manage.py migrate

      3.2,views 

    复制代码
     1 from app01 import models
     2 def signal(request):
     3     obj=models.User(user="root")
     4 
     5     print("end")
     6     obj.save()
     7 
     8     obj1=models.User(user="root1")
     9     obj1.save()
    10     return HttpResponse("TEST SIGNAL")
    复制代码

      urls

    path("signal/",views.signal),

    访问

      输入:

     所以我们看出来了,我们调用了数据库操作的信号,所以在所有的modles操作之前都有这个操作,这个只是插入数据库之前的操作,如果想要看更多操作,请看上面的操作。

    3.3、django信号创建流程

    
    

    四、自定义信号

      4.1、创建信号

        说明:pizza_done是信号名,providing_args=["toppings", "size"],这个是触发者的时候需要传递的参数    

    1 import django.dispath
    2 
    3 pizza_done=django.dispath.Signal(providing_args=["toppings","size"])

      4.2、注册信号    

    1 def callback(sender, **kwargs):  #创建注册信号的函数,这边的注册函数可以写多个
    2     print("callback")
    3     print(sender,kwargs)
    4   
    5 pizza_done.connect(callback)  #注册信号

      4.3、触发信号  

    1
    2
    3
    from 路径 import pizza_done
       
    pizza_done.send(sender='zhangqigao',toppings=123, size=456)

      下面搞栗子

      

      

    所以我们自定义信号的时候,我们自己触发就行了。那我们在什么情况下使用呢 ?

    答:你某个阀值,你去监控服务器,当到达某个状态的时候,就可以让他执行某个操作,等着你的要求,源码不要动,只需要注册信号就可以了。

    由于内置信号的触发者已经集成到Django中,所以其会自动调用,而对于自定义信号则需要开发者在任意位置触发。

    更多:猛击这里


  • 相关阅读:
    Oracle完全卸载
    Oracle数据库(64位) 及 PLSQL(64位)的组合安装【第一篇】
    Yii2 配置yii2redis扩展
    php 获取每个汉字的拼音首字母
    linux 安装memcacheq
    php在linux中执行外部命令
    比较两个日期的时间差精确到秒
    mysql 的 备份与还原
    php类中__get和__set的用法
    yii2.0 安装
  • 原文地址:https://www.cnblogs.com/gaodi2345/p/11579237.html
Copyright © 2011-2022 走看看