@ShawnFumo如果同一个模型同时保存在别处,则断开信号是危险的,不要这样做!
@Aram Dulyan,你的解决方案有效,但阻止你使用如此强大的信号!
如果你想避免递归并继续使用signals(),一个简单的方法是在当前实例上设置一个属性,以防止即将发出的信号.
这可以使用一个简单的装饰器来完成,该装饰器检查给定的实例是否具有'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
Run Code Online (Sandbox Code Playgroud)
我们现在可以这样使用它:
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()
Run Code Online (Sandbox Code Playgroud)
希望这可以帮助.
这将起作用:
class YourModel(models.Model):
name = models.CharField(max_length=50)
def save_dupe(self):
super(YourModel, self).save()
def save(self, *args, **kwargs):
super(YourModel, self).save(*args, **kwargs)
for model in YourModel.objects.exclude(pk=self.pk):
model.name = self.name
# Repeat the above for all your other fields
model.save_dupe()
Run Code Online (Sandbox Code Playgroud)
如果您有很多字段,则在将它们复制到其他模型时可能需要对其进行迭代。我留给你。
处理此问题的另一种方法是在保存时删除侦听器.所以:
class Foo(models.Model):
...
def foo_post_save(instance):
post_save.disconnect(foo_post_save, sender=Foo)
do_stuff_toSaved_instance(instance)
instance.save()
post_save.connect(foo_post_save, sender=Foo)
post_save.connect(foo_post_save, sender=Foo)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3453 次 |
| 最近记录: |