2012-01-07 53 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() 

希望這會有所幫助。