Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django get all descendant child models using django queryset

Tags:

python

django

I have user model with self referential. Now I need to get all children for given user.

class MyUser(AbstractBaseUser, PermissionsMixin):
      .....
      parent = models.ForeignKey('self', blank=True, null=True, related_name ='children')

User A has child User B

User B has child User C

Use C has child User D

So if I have User A as given then I want to get

User B,C,D as result

How to do that using django query ??

like image 221
Mridul Kumar Biswas Avatar asked Feb 25 '16 03:02

Mridul Kumar Biswas


1 Answers

A little late to the party, but I ran across the same problem. Selcuk's answer raises an AttributeError, I wrote an improved function (but kudos to them). For my use case, I also needed a way to find all parents, and I made sure to avoid the infinite loop by forbidding circular relationships in my clean method.

from django.core.exceptions import ValidationError

class MyUser(AbstractBaseUser, PermissionsMixin):
    parent = models.ForeignKey('self', blank=True, null=True, 
                related_name="children")

    def get_all_children(self):
        children = [self]
        try:
            child_list = self.children.all()
        except AttributeError:
            return children
        for child in child_list:
            children.extend(child.get_all_children())
        return children

    def get_all_parents(self):
        parents = [self]
        if self.parent is not None:
            parent = self.parent
            parents.extend(parent.get_all_parents())
        return parents

    def clean(self):
        if self.parent in self.get_all_children():
            raise ValidationError("A user cannot have itself \
                    or one of its' children as parent.")
like image 62
Celebrian Avatar answered Sep 22 '22 20:09

Celebrian