2012-01-07 49 views
3

我想通过处理post_save,delete和init信号来跟踪我的模型及其CRUD操作,然后将有关此操作处理的条目保存到数据库。Django从发送信号中排除模型

def handle_model_saved(sender, **kwargs): 
    """Trap the signal and do whatever is needed""" 
    entry=CRUD_Storage() 
    entry.entry='Object \"'+sender._meta.module_name+'\" was saved.' 
    entry.save() 

那么有趣的事情,它是可以节省的递归...

我创建的模型CRUD_Storage,我想阻止它发送信号像前(后)初始化,删除,保存。

回答

3

我不认为你可以阻止Django发送这些信号。

但是,您可以调整您的处理程序,以免为您的CRUD_Storage模型记录保存。

def handle_model_saved(sender, **kwargs): 
    """Trap the signal and do whatever is needed""" 
    if sender == CRUD_Storage: 
     # return early to prevent recursion of saves 
     return 
    entry=CRUD_Storage() 
    entry.entry='Object \"'+sender._meta.module_name+'\" was saved.' 
    entry.save() 
+0

谢谢,这似乎是一个沉闷的问题,然后......这么简单... – Feanor 2012-01-07 19:04:10

0

这里是驳回信号的方式。

如果要解除信号以避免递归,一个简单的方法是在当前实例上设置一个属性,以防止即将发生的信号触发。

这可以用一个简单的装饰来检查,如果给定的实例具有“skip_signal”属性来完成,如果是防止被调用的方法:

from functools import wraps 

def skip_signal(): 
    def _skip_signal(signal_func): 
     @wraps(signal_func) 
     def _decorator(sender, instance, **kwargs): 
      if hasattr(instance, 'skip_signal'): 
       return None 
      return signal_func(sender, instance, **kwargs) 
     return _decorator 
    return _skip_signal 

现在,我们可以用它这个方式:

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

@receiver(post_save, sender=MyModel) 
@skip_signal() 
def my_model_post_save(sender, instance, **kwargs): 
    # you processing 
    pass 

m = MyModel() 
# Here we flag the instance with 'skip_signal' 
# and my_model_post_save won't be called 
# thanks to our decorator, avoiding any signal recursion 
m.skip_signal = True 
m.save() 

希望这会有所帮助。