您的位置:首页 > 编程语言 > Go语言

Django Singal

2015-10-13 21:31 417 查看

Django Singal

Django有一个信号发布器——”signal dispatcher”来帮助解耦的应用当某一事件发生的时候获得通知。

内置信号

定义在文件django/db/models/signal.py之中的内置信号与model相关:

from django.dispatch import Signal

class_prepared = Signal(providing_args=["class"])

pre_init = Signal(providing_args=["instance", "args", "kwargs"])
post_init = Signal(providing_args=["instance"])

pre_save = Signal(providing_args=["instance", "raw", "using", "update_fields"])
post_save = Signal(providing_args=["instance", "raw", "created", "using", "update_fields"])

pre_delete = Signal(providing_args=["instance", "using"])
post_delete = Signal(providing_args=["instance", "using"])

post_syncdb = Signal(providing_args=["class", "app", "created_models", "verbosity", "interactive"])

m2m_changed = Signal(providing_args=["action", "instance", "reverse", "model", "pk_set", "using"])


定义在django/core/signal.py之中的内置信号与request相关:

from django.dispatch import Signal

request_started = Signal()
request_finished = Signal()
got_request_exception = Signal(providing_args=["request"])


由信号的名称即可看出各类信号在什么时机发送。

自定义信号

监听信号

信号是要先定义的,定义之后需要有监听的函数,当信号发送出来之后,所有的监听函数都会被调用。

监听信号使用的是Signal.connect()函数

Signal.connect(receiver, sender=None, weak=True, dispatch_uid=None)

Parameters:

receiver – The callback function which will be connected to this signal.

sender – Specifies a particular sender to receive signals from.

weak – Django stores signal handlers as weak references by default. Thus, if your receiver is a local function, it may be garbage collected. To prevent this, pass weak=False when you call the signal’s connect() method.

dispatch_uid – A unique identifier for a signal receiver in cases where duplicate signals may be sent.

示例:

首先定义一个receiver,这个receiver就是一个python的函数,当信号产生的时候,这个函数被执行。

def my_callback(sender, **kwargs):
print("Request finished!")


之后向request_finished信号注册该函数

from django.core.signals import request_finished
request_finished.connect(my_callback)


看上去比较复杂,有更为简洁的方法——使用python的装饰器

from django.core.signals import request_finished
from django.dispatch import receiver

@receiver(request_finished)
def my_callback(sender, **kwargs): print("Request finished!")


如此request_finished信号每一次发送之后my_callback()都会执行。

Sender

像上面这样注册信号,那么无论是谁发送该信号都会执行receiver,这里要说一个sender的概念,即是信号的发送者。可以向特定的sender进行注册信号

from django.db.models.signals import pre_save
from django.dispatch import receiver
from myapp.models import MyModel
@receiver(pre_save, sender=MyModel)
def my_handler(sender, **kwargs):
...


有一种做法是在receiver之中判定sender,这种效率不好。

@receiver(pre_save)
def my_handler(sender, **kwargs):
if sender==MyModel:
...


定义信号

class Signal(providing_args=list)


所有的信号都是django.dispatch.Signal的实例。参数providing_args是一个信号提供给接收函数的参数名称。但是这个只是一个文档规定,其实并不起实际作用。

import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])


这表示信号pizza_done会提供给receiver的参数为”toppings”, “size”。

发送信号

Django中有两种方式来发送信号:

Signal.send(sender, **kwargs)
Signal.send_robust(sender, **kwargs)


其中sender参数是必须提供的。例如:

class PizzaStore(object):
...

def send_pizza(self, toppings, size):
pizza_done.send(sender=self.__class__, toppings=toppings, size=size)
...


send()和send_robust()函数都返回一个元组对列表:[(receiver, response), … ]。表示调用的receiver和它们的返回值。

send()和send_robust()的区别在于send()并不catch异常,而send_robust()catch异常。

取消监听信号

Singal可以注册receiver也可以取消receiver的注册。使用的函数是:

Signal.disconnect(receiver=None, sender=None, weak=True, dispatch_uid=None)


如果receiver取消了监听返回True,不取消返回False。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: