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:

 def signal(request):
from app01 import models
obj = models.UserInfo(user='root')
print("end")
obj.save() obj = models.UserInfo(user='root')
obj.save() obj = models.UserInfo(user='root')
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

最新文章

  1. block为什么用copy以及如何解决循环引用
  2. String类型的属性和方法
  3. input输入样式,动画
  4. hihoCoder 1043 完全背包 (dp)
  5. android仿win8 metro磁贴布局
  6. [jobdu]孩子们的游戏(圆圈中最后剩下的数)
  7. UVA 5875 DP
  8. [译]ava 设计模式之享元
  9. vue视频学习笔记04
  10. cookie存储中文
  11. 1_Two Sum --LeetCode
  12. 从零部署Spring boot项目到云服务器(正式部署)
  13. P5302 [GXOI/GZOI2019]特技飞行
  14. Oracle 数据文件迁移
  15. thrift常见异常及原因分析(updating)
  16. VC++、MFC最好的开源项目
  17. FreeMaker常用表达式
  18. JVM总结-异常处理
  19. Eclipse集成SonarLint
  20. 一致性哈希算法——PHP实现代码

热门文章

  1. 类的成员变量修饰 const 和static
  2. git 沙河游戏节点图, 自由沙盒模拟git, 各类交互git命令
  3. 【Demo】CSS3 动画 加载进度条
  4. Granting and Managing Item Level Permission using SharePoint2013 Designer Workflow
  5. 将C语言的CRC32 代码转成JAVA的CRC32 代码
  6. BZOJ3239 Discrete Logging
  7. 博客(第0次作业)—— New Starting Point
  8. Jmeter-Transaction Controller(事务控制器)
  9. threejs 通过bufferGeometry处理每一个点的位置和颜色
  10. 2018c语言第2次作业