Django 信号

来源:互联网 发布:海康网络键盘视频教程 编辑:程序博客网 时间:2024/06/05 06:22

Django 信号

Django提供一种信号机制,一些动作发生时,会触发信号,然后监听了这个信号的函数就会被执行。比如,实现数据库每写入一条数据,写一条日志。要实现这个需求,可以通过全局的中间件来做,但是利用Django的信号机制会更灵活。中间件只作用在请求进来和响应出去时,而信号的散布范围更广。

我们先看看Django内置了哪些信号:

Model signals

pre_init                    # django的modal执行其构造方法前,自动触发post_init                   # django的modal执行其构造方法后,自动触发pre_save                    # django的modal对象保存前,自动触发post_save                   # django的modal对象保存后,自动触发pre_delete                  # django的modal对象删除前,自动触发post_delete                 # django的modal对象删除后,自动触发m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发

Management signals
pre_migrate # 执行migrate命令前,自动触发

Request/response signals
request_started # 请求到来前,自动触发
request_finished # 请求结束后,自动触发
got_request_exception # 请求异常后,自动触发

Test signals
setting_changed # 使用test测试修改配置文件时,自动触发

Database Wrappers
connection_created # 创建数据库连接时,自动触发

那么如何使用信号呢?

导入信号 –> 将回调函数注册到信号上 ;

注意,只有执行了注册代码,才能在信号发生时,执行注册的函数。因此,为了能在服务启动时,执行注册代码,应该将注册信号的操作写在项目的__init__.py

from django.db.models.signals import post_save  # 导入信号def callback1(sender, **kwargs):  # 定义回调函数, 作为信号的接收者    print('create a new user')    print(sender, kwargs)def callback2(sender, **kwargs):    passdef callback3(sender, **kwargs):    passpost_save.connect(callback1)# 我们也可以为信号注册多个函数# post_save.connect(callback2)# post_save.connect(callback3)

下面在视图中往数据库新增一条记录:

def add(request):    u = UserInfo(name='sb',pwd='123')    u.save()    return HttpResponse('save ok')

通过浏览器访问http://127.0.0.1:8000/add/来执行add视图,models.UserInfo触发信号,回调函数收到信号,执行。查看打印结果:

create a new user<class 'app01.models.UserInfo'> {'signal': <django.db.models.signals.ModelSignal object at 0x000001CA5118DDA0>, 'instance': <UserInfo: UserInfo object>, 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}

回调的方式注册信号,我们也可以通过装饰器的方式:

from django.db.models.signals import post_savefrom django.dispatch import receiver@receiver(post_save)def callback(sender, **kwargs):    pass

自定义信号

我们可以将自定义的信号单独写在一个脚本:

import django.dispatchmy_signal = django.dispatch.Signal(providing_args=['arg1', 'arg2'])# providing_args中的参数自定义

在项目的__init__.py中注册自定义信号:

from my_signal import my_signaldef callback(sender, **kwargs):    passmy_signal.connect(callback)

在需要用到自定义信号的地方,导入自定义信号,给它发送信号:

from my_signal import my_signalmy_signal.send(sender='', arg1='', arg2='')
原创粉丝点击