djangodjango-modelsdjango-signalsdjango-3.0

Maximum recursion depth exceeded in my Django signal


I have the following Django signal which basically triggers the signal to increase the points of my previous records in my postgres db by 5 when a new record is saved, but my Django signal saves the changes to 1 previous record and I get the error 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()

What am I doing wrong? I am using the .save() method to save the updated records in my db after a new record has been inserted.


Solution

  • Likely the point.save() triggers the same signal. So your signal triggers that signal, and thus this results in endless recursion.

    You can update the value with a query in bulk:

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

    This will not only circument the signalling problem, it will furthermore make a query in bulk, and is thus more efficient.

    Note that if you post_save, then the Task that was just added, will be part of the QuerySet. Perhaps you want to exclude that Task. In that case, we thus can implement this as:

    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)