父/子(ren)层次结构/“嵌套集”,在Python / Django中

时间:2010-06-29 19:07:29

标签: python django parent-child hierarchy

我正在使用Django / Python,但伪代码在这里肯定是可以接受的。

使用已经存在的某些模型,我有Employee个,每个都有一个Supervisor,它本质上是与另一个Employee的外键类型关系。

Employee / Supervisor层次结构是这样的:

任何给定的员工都有一名主管。该主管可能有一个或多个员工“在”下面,并且还有他/她自己的主管。检索我的“上线”应该返回我的主管,他的主管,她的主管等,直到找到没有主管的员工。

由于这是一个现有的代码库和项目,因此我不知道如何处理这些关系,我想知道实现以下功能的“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 :(得分:2)

您无需触摸模型即可使用django-mptt;您只需在模型上创建parent字段,当您注册模型时,django-mptt会自动创建mptt的所有其他属性:mptt.register(MyModel)

虽然如果你只需要'upline'层次结构,你就不需要嵌套集。更大的性能问题是相反的方向并收集例如。孩子/叶子等,这使得必须使用嵌套集模型!

答案 1 :(得分: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