我有一个要求,我需要能够在组织结构图类型的情况下创建多个节点。这些要求需要一个孩子"节点可以拥有多个父节点,因此不幸的是现有的解决方案如mptt
或treebeard
。
这些要求还规定我应该在任何级别访问节点,并能够根据其子节点开展业务。
这是我的尝试:
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
的两个子节点,并且child1
和child2
都未包含在返回的列表中。
答案 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)