@ ShawnFumo Отключение сигнала опасно, если одна и та же модель сохраняется в другом месте одновременно, не делайте этого!
@ Арам Дулян , ваше решение работает, но мешает вам использовать столь мощные сигналы!
Если вы хотите избежать рекурсии и продолжать использовать сигналы (), простой способ - установить атрибут для текущего экземпляра, чтобы предотвратить срабатывание предстоящих сигналов.
Это можно сделать с помощью простого декоратора, который проверяет, имеет ли данный экземпляр атрибут '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()
Надеюсь, это поможет.