递归深度未知的查询集列表

时间:2017-06-25 22:23:40

标签: python django python-3.x django-models generator

我有一个要求,我需要能够在组织结构图类型的情况下创建多个节点。这些要求需要一个孩子"节点可以拥有多个父节点,因此不幸的是现有的解决方案如mptttreebeard

这些要求还规定我应该在任何级别访问节点,并能够根据其子节点开展业务。

这是我的尝试:

class Division(models.Model):

    name = models.CharField(
        max_length=250,
    )
    children_set = models.ManyToManyField(
        to='organisations.Division',
        related_name='parent_set',
    )

    def _flatten_children(self, el):
        for item in el.children_set.all():
            if bool(item.children_set.count()):
                yield from self._flatten_children(item)
            else:
                yield item

    def all_children(self):
        return list(self._flatten_children(self))

    def add_child(self, child):
        self.children_set.add(child)

调用它时,我似乎只得到" last"的查询集。儿童。任何帮助将不胜感激。

# test setup
instance = DivisionFactory()
child1 = DivisionFactory()
child2 = DivisionFactory()
child3 = DivisionFactory()
child4 = DivisionFactory()

instance.add_child(child1)
child1.add_child(child2)
child2.add_child(child3)
child2.add_child(child4)

输出:

In [19]: instance.all_children()
Out[19]: [<Division: Officia dolores illo.>, <Division: Vitae sapiente numquam.>]

注意如何仅返回child2的两个子节点,并且child1child2都未包含在返回的列表中。

1 个答案:

答案 0 :(得分:1)

当前代码仅生成没有子项的项目。你需要全部收益(包括自我)

def _flatten_children(self, el):
    for item in el.children_set.all():
        if bool(item.children_set.count()):
            yield from self._flatten_children(item)
        yield item  # <----  # children first

def _flatten_children(self, el):
    for item in el.children_set.all():
        yield item  # <----  # parents first
        if bool(item.children_set.count()):
            yield from self._flatten_children(item)