Django 信号

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):
    pass

def callback3(sender, **kwargs):
    pass

post_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
'app01.models.UserInfo'> {'signal': at 0x000001CA5118DDA0>, 'instance': , 'created': True, 'update_fields': None, 'raw': False, 'using': 'default'}

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

from django.db.models.signals import post_save
from django.dispatch import receiver

@receiver(post_save)
def callback(sender, **kwargs):
    pass

自定义信号

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

import django.dispatch

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

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

from my_signal import my_signal

def callback(sender, **kwargs):
    pass

my_signal.connect(callback)

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

from my_signal import my_signal
my_signal.send(sender='', arg1='', arg2='')

你可能感兴趣的:(Django)