How to save a model without sending a signal?

前端 未结 6 2112
名媛妹妹
名媛妹妹 2021-02-06 23:23

How can I save a model, such that signals arent sent. (post_save and pre_save)

6条回答
  •  情话喂你
    2021-02-07 00:21

    As far as I'm aware there still isn't a 'nice' way to do this, but if you're open to exploring hacky solutions, then I'll add one to the mix.

    If you look at the django model source code, specifically save_base() here and here, you'll see that the pre_save() and post_save() signals are both wrapped in a conditional:

    if not meta.auto_created:
      // Emit signal
    

    We can directly manipulate the meta options of a model or instance through the _meta API which means we're able to 'disable' the signals from firing by setting auto_created = True on the instance we want to save.

    For example:

    @receiver(post_save, sender=(MyModel))
    def save_my_model(sender, instance=None, created=False, **kwargs):
        if created:
            # Modify the instance
            instance.task_id = task.task_hash
    
            # HACK: Prevent `post_save` signal from being called during save
            instance._meta.auto_created = True
            instance.save()
            instance._meta.auto_created = False
    
        elif instance.has_changed("schedule"):
            # Modify the instance
            instance.task_id = 'abc123'
    
            # HACK: Prevent `post_save` signal from being called during save
            instance._meta.auto_created = True
            instance.save()
            instance._meta.auto_created = False
    

    The major caveat here is that this is undocumented behaviour and it could well change it future releases of django.

提交回复
热议问题