这种实现应该有效
def get_family_tree(person):
""" return a family tree for a Person object """
children = person.children.all()
if not children:
# this person has no children,recursion ends here
return {'name': person.name,'children': []}
# this person has children,get every child's family tree
return {
'name': person.name,'children': [get_family_tree(child) for child in children],}
请注意,这将占用与人员一样多的数据库调用.如果遇到性能问题,可以尝试将所有数据提取到内存中.
关于递归的思考
考虑递归的一种方法是从基本情况开始 – 即递归结束的地方.在您的情况下,我们知道如果一个人没有孩子,家谱如何:
{
'name': 'FirstPerson','children': [],}
在有了基本案例之后,考虑一下你必须执行递归的问题.
在你的情况下,这将是有孩子的父母,但没有大孩子.我们知道每个孩子的家谱应该如何看 – 这只是基本情况!这引出了我们返回父级名称的解决方案,以及每个孩子的家谱的列表.导致类似于:
{
'name': FirstPerson,'children': [
编辑
Django自动为ForeignKey生成反向关系.
class Person(models.Model):
....
parent = models.ForeignKey('self',related_name='children',blank=True,null=True)
p = Person()
p.children.all() # automatically fetch all Person objects where parent=p