【问题标题】:Maximum recursion depth exceeded in my Django signal我的 Django 信号超出了最大递归深度
【发布时间】:2019-12-26 18:43:19
【问题描述】:

我有以下 Django 信号,当保存新记录时,它基本上触发信号将我的 postgres db 中以前记录的点数增加 5,但是我的 Django 信号将更改保存到 1 个以前的记录,我得到了错误RecursionError: Maximum recursion depth exceeded

# models.py

from django.db.models.signals import post_save    

class Task(models.Model):
    ....


def update_points(sender, instance, **kwargs):

    qs = Task.objects.filter(status='Active')

    for task in qs:
        task.points = task.points + 5
        task.save() 

我做错了什么?在插入新记录后,我正在使用 .save() 方法将更新的记录保存在我的数据库中。

【问题讨论】:

  • task.save() 可能会触发 same 信号(因此会一直触发该信号)。
  • 啊哈!那么,我应该如何更新那些以前的记录,而不是 task.save()?

标签: django django-models django-signals django-3.0


【解决方案1】:

point.save() 可能会触发相同的信号。因此,您的信号会触发该信号,从而导致无限递归。

您可以通过查询批量更新值:

from django.db.models import F 

def update_points(sender, instance, **kwargs):
    Task.objects.filter(status='Active').update(points=F('points')+5)

这不仅可以规避信令问题,还可以批量进行查询,效率更高。

请注意,如果您是post_save,那么刚刚添加的Task 将成为QuerySet 的一部分。也许您想排除 Task。在这种情况下,我们可以将其实现为:

from django.db.models import Q, F
from django.db.models.signals import post_save

def update_points(sender, instance, created, **kwargs):
    if created:
        Task.objects.filter(~Q(pk=instance.pk), status='Active').update(
            points=F('points')+5
        )

post_save.connect(update_points, sender=Task)

【讨论】:

  • 正确!我想排除那个新添加的任务。
  • 感谢威廉·范昂塞姆。经过大量谷歌搜索后,我遇到了同样的问题并在这里找到了您的解决方案:)
猜你喜欢
  • 2017-08-09
  • 2011-03-31
  • 1970-01-01
  • 2013-02-20
  • 1970-01-01
  • 1970-01-01
  • 2013-12-01
  • 1970-01-01
相关资源
最近更新 更多