1. 基本概念
Django内置了一个信号分发器。信号可以帮助解耦程序模块。在应用中其他地方发生某事件时,通知指定函数。信号允许某些 senders 通知一组 receivers 已经发生的行为。
2. 信号使用
2.1 声明信号
在使用信号之前,首先得创建信号实例,声明信号的接收参数列表。django.dispatch.Signal是Django提供的信号类,其构造方法接收一个参数providing_args,指明信号包含的参数。
1
2
3
|
from django.dispatch import Signal
# 声明一个名为mysignal的信号实例
mysignal=Signal(providing_args=['user'])
|
2.2 发送信号
当需要通知接收者处理信号时,首先需要发送者发送一个signal。Signal类提供了两种方法,用于发送信号。
1
2
|
Signal.send(sender, **named)
Signal.send_robust(sender, **named)
|
两种方法都返回一个含有二元组的列表 [(receiver, response), … ],表示全部的接收函数和响应值。不同之处在于异常处理部分,send( )不会捕捉receiver产生的异常,而send_robust( )会。
1
2
3
4
|
def home(request):
mysignal.send(sender=None,user=request.user)
# send方法第一个参数为sender,可以是对象.__class__、self、直接类名
return HttpResponseNotAllowed('')
|
2.3 关联处理函数
第一种,使用connect方法。
1
|
Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)
|
- receiver:signal的接收者
- sender:signal的发送者
- weak:Django默认将signal处理器当成弱引用存储。因此,如果接收函数是本地函数的话,有可能被垃圾回收。为防止这种情况,需要指定weak=False。
- dispatch_uid:信号有可能重复发送的情况下,信号处理器的唯一标识 定义一个receiver(也可以说是一个call_back函数):
1
|
mysignal.connect(record)
|
第二种,使用装饰器。
1
2
3
4
5
6
|
from django.dispatch import receiver
@receiver(mysignal)
def record(sender,user,**kwargs):
#执行函数第一个参数为sender
print user.username
|
通过装饰器修饰,可以指定信号的处理函数。receiver也接受sender参数,仅处理指定发送者的信号。第三种,使用dispatcher。
1
2
3
|
from django.db.models.signals import post_save
from django.dispatch import dispatcher
dispatcher.connect(receiver=record, signal=post_save, sender=Mymodel)
|
dispatcher显式的指出了处理函数,信号,发送者。
2.3 处理信号
信号的处理是通过调用处理函数实现的。
1
2
|
def callback_func(sender, **kwargs):
pass
|
所有的信号处理函数,都必须接收一个sender参数,以及通配符关键字参数(**kwargs)
2.4 断开信号
1
|
Signal.disconnect(receiver=None, sender=None, weak=True, dispatch_uid=None):
|
如果接收器成功断开,返回 True ,否则返回False。
3. Django内置信号
Django内置的信号是已经实例化的Signal类。在使用时,省掉了声明信号,发送信号两个流程。将Django内置的信号直接关联上自定义的处理函数,即可使用。下面是Django内置信号列表:django.db.models.signals
1
2
3
4
5
6
7
8
9
10
11
12
|
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类,对于每一个类,自动触发
pre_migrate # 执行migrate命令前,自动触发
post_migrate # 执行migrate命令后,自动触发
pre_syncdb # 执行syncdb命令前,自动触发
post_syncdb # 执行syncdb命令后,自动触发
|
django.core.signals
1
2
3
4
|
request_started # 请求到来前,自动触发
request_finished # 请求结束后,自动触发
got_request_exception # 请求异常后,自动触发
setting_changed # settings发生改变时,自动触发
|
django.test.signals
1
|
template_rendered # 使用test测试渲染模板时,自动触发
|
django.db.backends.signals
1
|
connection_created # 创建数据库连接时,自动触发
|
例如,需要在每次完成请求后,进行某些操作,可以这样写:
1
2
3
4
5
|
from django.core.signals import request_finished
from django.dispatch import receiver
@receiver(request_finished)
def callback_func(sender,**kwargs):
print('request finished')
|
4. 参考
- 1.http://python.usyiyi.cn/translate/django_182/topics/signals.html
- 2.http://lilongzi.blog.51cto.com/5519072/1906557