我想通过处理post_save,delete和init信号来跟踪我的模型及其CRUD操作,然后将关于此操作的条目保存到数据库中。
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,我想阻止它发送pre(post)init,delete,save等信号。
答案 0 :(得分: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()
答案 1 :(得分:0)
这是解除信号的 DRY 方式。
如果要关闭信号以避免递归,一个简单的方法是在当前实例上设置属性以防止即将发出的信号。
这可以使用一个简单的装饰器来完成,该装饰器检查给定实例是否具有'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()
希望这有帮助。