有许多关于使用post_save信号的递归的Stack Overflow帖子,对这些帖子的 comments 和答案都是压倒性的:"为什么不覆盖save()"或者只在created == True上触发的save.

我认为不使用save()是一个很好的理由——例如,我添加了一个临时应用程序,它处理订单履行数据,完全独立于我们的订单模型.

框架的睡觉幸运地不知道执行应用程序,并且使用POST_SAVE挂钩将所有与执行相关的代码从我们的订单模型中隔离出来.

如果我们放弃履行服务,我们的核心代码就不会有任何改变.我们删除了履行应用程序,仅此而已.

那么,有没有什么好的方法来确保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

您还可以创建decorator

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()

Django相关问答推荐

测试DRF中需要授权头

Django Prefetch上的多重过滤

如何在Django中将可选参数传递给视图?

当使用django-tinymce时,我在哪里指定referer?

错误404除主要应用程序外,HTML页面无法渲染的其他应用程序

使用 Crispy Forms 时 Django 返回 'TemplateDoesNotExist'

Django 关系嵌套related_name

使用 Django 一次更新多条记录

Django 视图 - 首先从调用应用程序的目录加载模板

InvalidBasesError:无法解析 [] 的基础

为什么 django 1.7 会为字段 Select 的变化创建迁移?

Django error:不能分配必须是实例

将现有 auth.User 数据迁移到新的 Django 1.5 自定义用户模型?

Django,如何从模型表单的 Select 字段中删除空白 Select ?

Django BigInteger自动增量字段作为主键?

django中的脏字段

AssertionError: `HyperlinkedIdentityField` 需要序列化程序上下文中的请求

django 如何知道已经运行了哪些迁移?

Django Admin - save_model 方法 - 如何检测字段是否已更改?

获取'str'对象在Django中没有属性'get'