Python/Django中的父子层级/嵌套集合
我正在使用Django/Python,不过这里用伪代码也可以。
我在处理一些已经存在的模型,其中有Employee
(员工),每个员工都有一个Supervisor
(主管),这实际上是指向另一个Employee
的外键关系。
员工和主管的层级关系大致是这样的:
每个员工只有一个主管。这个主管可能会有一个或多个“下属”员工,同时他/她自己也有主管。获取我的“上级”应该返回我的主管,他的主管,她的主管,等等,直到找到一个没有主管的员工为止。
在不疯狂安装新应用来管理这些关系的情况下,因为这是一个已有的代码基础和项目,我想知道实现以下功能的“pythonic”或正确方法是什么:
def get_upline(employee):
# Get a flat list of Employee objects that are
# 'supervisors' to eachother, starting with
# the given Employee.
pass
def get_downline(employee):
# Starting with the given Employee, find and
# return a flat list of all other Employees
# that are "below".
pass
我觉得用Django的ORM可能有比较简单的方法来做到这一点,但如果没有,我也欢迎任何建议。
我还没有仔细研究Django-MPTT,但如果我能保持模型不变,同时获得更多功能,那就值得尝试。
2 个回答
0
关系型数据库不太适合处理这种图形查询,所以你唯一的选择就是进行很多次查询。下面是一个递归的实现方式:
def get_upline(employee):
if self.supervisor:
return [employee] + self.supervisor.get_upline()
else:
return [employee]
def get_download(employee):
l = [employee]
for minion in self.minion_set.all():
l.extend(minion.get_download())
return l
2
你不需要修改你的模型就可以使用django-mptt;只需要在你的模型中创建一个parent
字段,django-mptt会自动为你生成其他需要的属性,当你注册你的模型时:mptt.register(MyModel)
。
不过,如果你只需要“上级”层级结构,那就不需要使用嵌套集合。更大的性能问题在于反向操作,比如收集子节点或叶子节点等,这就需要使用嵌套集合模型了!