仅为当前对象调用信号

时间:2017-03-16 09:06:13

标签: python django model signals

我正在使用django 1.6处理信号。 我的模型Events带有字段is_cyclic,我想只为一个当前对象运行信号。但似乎我的代码遍历所有对象,我收到错误:

maximum recursion depth exceeded while calling a Python object

这是我的信号

@receiver(post_save, sender=Events)
def my_callback(sender, created, instance, *args, **kwargs):
    db_name = args[0] if len(args) else 'events'
    print('using %s' % db_name)
    list = loader.get_template('events/event_list_item.html')
    list_small = loader.get_template('events/event_list_item_small.html')
    setattr(instance, 'is_cyclic', list.render(Context({'e': instance})))
    setattr(instance, 'is_cyclic', list_small.render(Context({'e': instance})))
    instance.save(using=db_name)

1 个答案:

答案 0 :(得分:2)

你读过你的代码吗?您有一个调用Event.save()的函数,并将其绑定到models.post_save()模型的Event信号。

保存模型实例后发送

models.post_save()信号。所以当你的回调调用instance.save()时,它会触发post_save信号,该信号调用你的回调函数,该函数会保存实例,触发post_save信号,调用你的回调函数,从而节省实例,触发post_save信号,调用你的回调函数等等。

你真的很幸运,Python将递归限制在给定的深度,否则这将永远递归。

作为旁注:

  • 您不需要setattr(),您可以使用明显的instance.is_cyclic = <whatever>属性分配语法
  • 您将相同的属性设置为两个不同的值,因此第一个被第二个替换,IOW第一个setattr调用纯粹是浪费时间
  • 我真的不明白为什么要将模板渲染的结果分配给实例属性(如果你想要缓存,Django已经有了一个全功能的缓存框架)。
  • 我完全不明白你为什么要把它分配给一个名字暗示一些布尔标志的属性