有很多关于使用post_save信号进行递归的Stack Overflow帖子,其中的注释和答案绝大多数是“为什么不重写save()”或仅在其上触发的保存created == True。
post_save
created == True
好吧,我相信有一个不使用的好例子save()-例如,我正在添加一个临时应用程序,该应用程序处理与订单模型完全不同的订单履行数据。
save()
框架的其余部分非常高兴地没有意识到实现应用程序,并且使用post_save挂钩将所有与实现相关的代码与我们的Order模型隔离开来。
如果我们放弃履行服务,则无需更改核心代码。我们删除履行应用程序,仅此而已。
因此,是否有任何体面的方法来确保post_save信号不会两次触发同一处理程序?
您如何看待该解决方案?
@receiver(post_save, sender=Article) def generate_thumbnails(sender, instance=None, created=False, **kwargs): if not instance: return if hasattr(instance, '_dirty'): return do_something() try: instance._dirty = True instance.save() finally: del instance._dirty
您也可以创建装饰器
def prevent_recursion(func): @wraps(func) def no_recursion(sender, instance=None, **kwargs): if not instance: return if hasattr(instance, '_dirty'): return func(sender, instance=instance, **kwargs) try: instance._dirty = True instance.save() finally: del instance._dirty return no_recursion @receiver(post_save, sender=Article) @prevent_recursion def generate_thumbnails(sender, instance=None, created=False, **kwargs): do_something()
你可以使用更新而不是保存在信号处理程序中
queryset.filter(pk = instance.pk).update(....)