[Django]-Limit Recursive Foreign Key Depth in Django Model

-1👍

Unfortunately, as explained very well in this answer, there really isn’t a good way to do this in Django. For example, the method above will simply crash the admin with a 500 error every time an end user hits the save button on a change form — hardly helpful. The only proper way to do this is to define clean_{fieldname} and throw a ValidationError. It doesn’t validate, for example, a model.save() from the manage.py shell, but neither will overriding that validate, for instance, queryset.update().

Therefore, the solution I went with now looks like this:

def clean_parent(self):
    depth = 0
    model = self.instance
    while model.parent is not None:
        depth += 1
        model = model.parent
    if depth > 10:
        raise ValidationError('Recursion Depth Exceeded')

Note this belongs in the admin form for the model.

4👍

Maybe something like this?

def save(self, *args, **kwargs):
    if Foo.objects.filter(foo=self.foo).count() > 10:
        raise Exception("not more than 10")
    else:
        super(Foo, self).save(*args, **kwargs)

Update:

For self referential fields with django-mptt you could do something like this:

def save(self, *args, **kwargs):
    if Foo.objects.filter(foo=self.foo).get_descendant_count() > 10:
        raise Exception("not more than 10")
    else:
        super(Foo, self).save(*args, **kwargs)

0👍

Version without cycle:

    def clean_parent(self):
        parent = self.cleaned_data['parent']
        if parent and parent.level >= 10:
            raise ValidationError('Recursion Depth Exceeded')
        return parent

Note: levels starts from 0.

Leave a comment