zoukankan      html  css  js  c++  java
  • Django学习---信号

    Django学习之信号

    如果我想对所有在数据库创建数据的时候记录一条日志。

    比如我们在django中往数据库中增加一条数据,希望生成一条操作日志,或者在数据保存和数据保存之后都保存一条操作日志,那我们应该怎么办呢?

    有很多人可能会想到用装饰器来实现,但是 装饰器一般是写在函数上面的,如果我们在函数中执行了不止一条数据库操作(如下面的代码),那记录下来的只能只有一条数据日志,也就是说装饰器只有在统一操作的时候记录下东西。

    def signal(request):
        from app01 import models
        obj = models.UserInfo(user='root')
        obj.save()
    
        obj = models.UserInfo(user='root')
        obj.save()
    
        obj = models.UserInfo(user='root')
        obj.save()

    那我们应该怎么做呢?

    在django中,django在创建这个对象的前后预留了两个位置,在models.UserInfo()前后留了两个位置,在obj.save前后也留了两个位置,相当于有4个位置可以进行操作

    我们查看一下save函数的源代码,发现save_base函数中触发了一个信号, 在这个post_save信号中我们可以注册很多函数,比如3个函数,如果我们一运行save函数,执行到post_save.send, 它会把那3个函数挨个执行一遍。

    那我们只要找到这个信号,往这个信号中注册一个函数:一旦写了这个操作就帮你记录一下。就可以了。而我们程序的内部一点都不需要改动

    django中内置信号:

    Model signals
        pre_init                    # django的modal执行其构造方法前,自动触发
        post_init                   # django的modal执行其构造方法后,自动触发
         如:models.UserInfo() pre_save # django的modal对象保存前,自动触发 post_save # django的modal对象保存后,自动触发
         如:obj.save() pre_delete # django的modal对象删除前,自动触发 post_delete # django的modal对象删除后,自动触发
         如:remove() 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 # 创建数据库连接时,自动触发

     应用:

    1.我们先创建一个sg.py用来存放信号,并写上函数:

    from django.core.signals import request_finished
    from django.core.signals import request_started
    from django.core.signals import got_request_exception
    
    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
    
    from django.test.signals import setting_changed
    from django.test.signals import template_rendered
    
    from django.db.backends.signals import connection_created
    
    
    def f1(sender, **kwargs):#这两个参数都会传到信号中的参数中
        print("xxoo_callback")
        # print(sender, kwargs)
    #按顺序执行
    pre_init.connect(f1)
    # xxoo.connect(callback)
    # xxoo指上述导入的内容

    这里面想要用哪个信号就导入哪个

    2.项目目录中的init.py中导入sg.py:

     

    views.py:

     1 def signal(request):
     2     from app01 import models
     3     obj = models.UserInfo(user='root')
     4     print("end")
     5     obj.save()
     6 
     7     obj = models.UserInfo(user='root')
     8     obj.save()
     9 
    10     obj = models.UserInfo(user='root')
    11     obj.save()

    我们先注释掉print(sender,kwargs)看看运行效果

     

    当然我们感觉如果内置的信号不够用 的话,我们还可以自定义信号:

    1.创建一个信号

    import django.dispatch
    pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])#send中的参数

    2.在信号中注册函数

    def callback(sender, **kwargs):
        print("callback")
        print(sender,kwargs)
     
    pizza_done.connect(callback)

    3.主动触发信号

    from 路径 import pizza_done
     
    pizza_done.send(sender='seven',toppings=123, size=456)

     和django的源码差不多,都调用send

  • 相关阅读:
    Python3 tkinter基础 Canvas create_text 在画布上添加文字
    js中如何返回一个存放对象的数组?
    vs2015 出现Lc.exe 已退出,代码为-1的问题,如何解决
    微信PC客户端无法发送图片,怎么解决?
    vs2015 编译时项目出现NuGet程序包还原失败,找不到xxx.xxx.xxx版本的程序包,怎么解决这个问题?
    sql server 根据身份证号计算出生日期和年龄的存储过程
    sql server中截取字符串的常用函数
    sql server 中进行除法运算时,如何得到结果是小数形式呢?
    sql中,如何获取一个数的整数部分和余数部分
    sql 中,如何获取两个日期之前月数、周数、天数
  • 原文地址:https://www.cnblogs.com/charles8866/p/8878786.html
Copyright © 2011-2022 走看看