【发布时间】:2018-04-28 05:53:13
【问题描述】:
我正在尝试基于一个模型创建一个组织结构图,该模型通过一个名为reports_to 的属性引用自身。我不知道组织结构图会下降多少层,所以我觉得递归函数很有意义。下面是一些目前有效的代码:
top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
org_chart[person] = {}
if person.has_direct_reports():
direct_reports = Person.objects.filter(reports_to=person)
for p in direct_reports:
org_chart[person][p] = {}
if p.has_direct_reports():
direct_reports_2 = Person.objects.filter(reports_to=p)
for q in direct_reports_2:
org_chart[person][p][q] = {}
# ... and so on
这会产生这样的 shell 输出:
>>> pp.pprint(org_chart)
{ <Person: Joe Boss>: { <Person: John Doe>: { <Person: John Doe Jr>: { },
<Person: Jane Doe>: { }}},
<Person: Partner Mary>: {}}
这是正确的。显示清洁剂:
Joe Boss
- John Doe
-- John Doe Jr
-- Jane Doe
Partner Mary
我一直在尝试将此代码转换为递归函数,但我的大脑无法解决这个问题。感谢您提供解决此问题的任何建议或帮助!
编辑。这是我正在尝试制作的代码,但在此过程中我陷入了困境:
def direct_reports_r(person):
if person.has_direct_reports():
direct_reports = Person.objects.filter(reports_to=person)
for person in direct_reports:
org_chart[person] = {}
if person.has_direct_reports():
direct_reports = Person.objects.filter(reports_to=person)
org_chart[person] = direct_reports_r(person)
else:
return person
else:
return False
top_level = Person.objects.filter(reports_to=None)
org_chart = {}
for person in top_level:
org_chart[person] = {}
# recursion
org_chart[person][direct_reports_r(person)] = {}
【问题讨论】:
-
听起来像图形搜索(编辑:实际上是的,它只是树遍历,因为没有循环)。无论如何,如果你重构
Person会更容易,所以它有一个direct_reports属性/方法 - 与reports_to的方向相反,但可能是一对多的。然后if person.has_direct_reports(); direct_reports = Person.objects.filter(reports_to=person); for p2 in direct_reports也简化为for p2 in person.direct_reports() -
我还没有听说过图搜索或树!这么多学习去做。谢谢。
-
您的代码中有一个错误:您重新声明了
for person in direct_reports,但这会掩盖调用它的person。最好叫它subordinate或dr或p2或其他任何名称