user3541631
user3541631

Reputation: 4008

Recursion error calling a function using a post-save signal

I have a Category model, where the ForeignKey is to self.

class Category(SEO, MetaData):
    parent = models.ForeignKey('self', blank=True, null=True, verbose_name='parent category', on_delete=models.CASCADE)
    path = ArrayField(models.IntegerField(), blank=True, null=True)

I introduced the path field, to avoid recursion in widget, and do it model, because is not often done.

I use a post_save signal to ssave the path:

def _recurse_for_parent(cat_obj, path=None):
    # path at the beginning don't exist and need to be initialized
    if not path:
        path = []
    if cat_obj.parent is not None:
        _recurse_for_parent(cat_obj.parent, path)
    return path


def save_path(sender, instance, **kwargs):
    if instance.parent_id:
        instance.children = _recurse_for_parent(instance.parent)
        instance.save()



post_save.connect(save_path, sender=Category)

My issue is that I get the "maximum recursion depth error" and I don't see why, because I use the condition:

cat_obj.parent is not None:

Upvotes: 1

Views: 328

Answers (2)

user3541631
user3541631

Reputation: 4008

I found the error in def save_path I call instance.save(), which will trigger the post_save signal.

Because post_save signal calls save_path and save path calls save which trigger post_save, I'm entering in an infinite loop.

I solved by moving my logic to the save method.

Upvotes: 2

luxcem
luxcem

Reputation: 1854

You have multiple issues in the function

def _recurse_for_parent(cat_obj, path=None):
    # path at the beginning don't exist and need to be initialized
    if not path:
        path = []
    if cat_obj.parent is not None:
        _recurse_for_parent(cat_obj.parent, path)
    return path

First have in mind that not [] will return True, so if you set path to [] the function will do the same thing every time. Use is None instead

Second the value from the recursive call is never used.

Finally think of what will append when both condition are True.

Upvotes: 0

Related Questions