django中得signals和操作系统(linux)中的signal完全是两会事,后者的signal是软件中断,提供一种处理异步事件得方法,信号是系统定义好的,可用作进程间传递消息得一种方法,而django中的信号只是一个普通的类,不能跨进程,看其代码更像一个。。。callback。。。

django signal类定义在django/dispatch/dispatch.py中

class Signal(object):
 
    def __init__(self, providing_args=None):
        #providing_args 定义receiver调用参数格式,为None也没关系
        self.receivers = []
        ......

    def connect(self, receiver, sender=None, weak=True, dispatch_uid=None):
        #看清楚了,其实就是把receiver保存起来,receiver是一个函数对象,就是该signal得handler
        ......
        if dispatch_uid:
            lookup_key = (dispatch_uid, _make_id(sender))
        else:
            lookup_key = (_make_id(receiver), _make_id(sender))

        ......

        self.lock.acquire()
        try:
            for r_key, _ in self.receivers:
                if r_key == lookup_key:
                    break
            else:
                self.receivers.append((lookup_key, receiver))
        finally:
            self.lock.release()

    def disconnect(self, receiver=None, sender=None, weak=True, dispatch_uid=None):
        #取消connect,把receiver从self.receivers删除就行了
        ......
         
    def send(self, sender, **named):
        #在事件发生时调用,发出信号,如有receive connect该信号,则调用之
        responses = []
        if not self.receivers:
            return responses

        for receiver in self._live_receivers(_make_id(sender)):
            response = receiver(signal=self, sender=sender, **named)
            responses.append((receiver, response))
        return responses

    def send_robust(self, sender, **named):
        #基本同上
        ......
    def _live_receivers(self, senderkey):
        #从self.receivers中找出相应得receiver
        ......
    def _remove_receiver(self, receiver):
        """
        Remove dead receivers from connections.
        """
        ......

整个信号得定义就这么简单,再来看看django中已定义好得一些signal, 在django/db/models/signal.py中

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"])
post_save = Signal(providing_args=["instance", "raw", "created", "using"])

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"])

他们中比如pre_init是在model实例之前会触发, post_init是在model实例化之后触发。 pre_save是在保存之前触发, post_save是保存之后触发。他们真正得实现机制看代码django/db/models/base.py处, 如下:

class Model(object):
   ......

    def __init__(self, *args, **kwargs):
        signals.pre_init.send(sender=self.__class__, args=args, kwargs=kwargs)

       ......
        signals.post_init.send(sender=self.__class__, instance=self)
    
    def save_base(self, raw=False, cls=None, origin=None, force_insert=False,
            force_update=False, using=None):
       
        ......
        if origin and not meta.auto_created:
            signals.pre_save.send(sender=origin, instance=self, raw=raw, using=using)

       ......

        # Signal that the save is complete
        if origin and not meta.auto_created:
            signals.post_save.send(sender=origin, instance=self,
                created=(not record_exists), raw=raw, using=using)
    


so, that all
无觅关联推荐,快速提升流量