Django学习---信号
2024-08-23 01:01:39
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
最新文章
- block为什么用copy以及如何解决循环引用
- String类型的属性和方法
- input输入样式,动画
- hihoCoder 1043 完全背包 (dp)
- android仿win8 metro磁贴布局
- [jobdu]孩子们的游戏(圆圈中最后剩下的数)
- UVA 5875 DP
- [译]ava 设计模式之享元
- vue视频学习笔记04
- cookie存储中文
- 1_Two Sum --LeetCode
- 从零部署Spring boot项目到云服务器(正式部署)
- P5302 [GXOI/GZOI2019]特技飞行
- Oracle 数据文件迁移
- thrift常见异常及原因分析(updating)
- VC++、MFC最好的开源项目
- FreeMaker常用表达式
- JVM总结-异常处理
- Eclipse集成SonarLint
- 一致性哈希算法——PHP实现代码
热门文章
- 类的成员变量修饰 const 和static
- git 沙河游戏节点图, 自由沙盒模拟git, 各类交互git命令
- 【Demo】CSS3 动画 加载进度条
- Granting and Managing Item Level Permission using SharePoint2013 Designer Workflow
- 将C语言的CRC32 代码转成JAVA的CRC32 代码
- BZOJ3239 Discrete Logging
- 博客(第0次作业)—— New Starting Point
- Jmeter-Transaction Controller(事务控制器)
- threejs 通过bufferGeometry处理每一个点的位置和颜色
- 2018c语言第2次作业