简体   繁体   English

Django使用django queryset获取所有后代子模型

[英]Django get all descendant child models using django queryset

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 用户A具有子用户B.

User B has child User C 用户B有子用户C.

Use C has child User D 使用C有子用户D

So if I have User A as given then I want to get 因此,如果我有给定的用户A,那么我想得到

User B,C,D as result 用户B,C,D作为结果

How to do that using django query ?? 如何使用django查询?

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. 对于我的用例,我还需要一种方法来查找所有父项,并且我确保通过在我的clean方法中禁止循环关系来避免无限循环。

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.")

There is no built-in query, but you can write your own (recursive) method: 没有内置查询,但您可以编写自己的(递归)方法:

class MyUser(AbstractBaseUser, PermissionsMixin):
    ...
    def get_all_children(self):
        children = []
        for u in self.children.all():
            children.append(u.get_all_children())
        return children

Please note that if you accidentally link an instance to itself (ie. child==parent) this will enter into an infinite loop. 请注意,如果您不小心将实例链接到自身(即.child == parent),这将进入无限循环。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM