Yuj*_*ita 32 python django django-signals
有许多关于使用post_save信号递归的Stack Overflow帖子,评论和答案都是压倒性的:"为什么不覆盖save()"或者只是触发的保存created == True.
我相信不使用的好例子save()- 例如,我正在添加一个临时应用程序来处理与Order模型完全分开的订单履行数据.
框架的其余部分幸福地没有意识到实现应用程序,并且使用post_save挂钩从我们的订单模型中隔离所有与履行相关的代码.
如果我们放弃履行服务,我们的核心代码就不得不改变.我们删除了履行应用程序,就是这样.
那么,是否有任何不错的方法来确保post_save信号不会两次触发相同的处理程序?
mos*_*lix 79
您可以使用更新而不是保存在信号处理程序中
queryset.filter(pk=instance.pk).update(....)
小智 36
不要断开信号.如果在信号断开时生成任何相同类型的新模型,则不会触发处理函数.信号在Django中是全局的,并且可以同时运行多个请求,使得一些请求失败而其他请求运行其post_save处理程序.
xak*_*dog 27
您对此解决方案的看法如何?
@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
Run Code Online (Sandbox Code Playgroud)
您还可以创建装饰器
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()
Run Code Online (Sandbox Code Playgroud)
Run*_*ard 26
我认为save_without_signals()在模型上创建方法更明确:
class MyModel()
def __init__():
# Call super here.
self._disable_signals = False
def save_without_signals(self):
"""
This allows for updating the model from code running inside post_save()
signals without going into an infinite loop:
"""
self._disable_signals = True
self.save()
self._disable_signals = False
def my_model_post_save(sender, instance, *args, **kwargs):
if not instance._disable_signals:
# Execute the code here.
Run Code Online (Sandbox Code Playgroud)
dge*_*gel 19
如何断开然后重新连接post_save函数内的信号:
def my_post_save_handler(sender, instance, **kwargs):
post_save.disconnect(my_post_save_handler, sender=sender)
instance.do_stuff()
instance.save()
post_save.connect(my_post_save_handler, sender=sender)
post_save.connect(my_post_save_handler, sender=Order)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16075 次 |
| 最近记录: |