Отключение сигнала не является решением DRY и согласованным , таким как использование update () вместо save ().
Для обхода срабатывания сигнала на вашеммодель, простой способ - установить атрибут в текущем экземпляре, чтобы предотвратить срабатывание предстоящих сигналов.
Это можно сделать с помощью простого декоратора, который проверяет, имеет ли данный экземпляр '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):
instance.some_field = my_value
# Here we flag the instance with 'skip_signal'
# and my_model_post_save won't be called again
# thanks to our decorator, avoiding any signal recursion
instance.skip_signal = True
instance.save()
Надеюсь, что это помогает.