Python/Django中的父/子层次结构/“嵌套集合”

3

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

在处理一些已经存在的模型时,我有一些员工(Employee),每个员工都有一个主管(Supervisor),它实际上是另一个员工(Employee)的ForeignKey类型关系。

员工/主管层次结构如下:

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

不要安装新应用程序来管理这些关系,因为这是现有的代码库和项目,我想知道实现以下函数的“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个回答

2
您不需要修改您的模型即可使用django-mptt;您只需在您的模型上创建一个parent字段,当您注册您的模型:mptt.register(MyModel)时,django-mptt会自动为mptt创建所有其他属性。如果您只需要“上级”层次结构,则不需要嵌套集。更大的性能问题是反向收集例如子代/叶等,这使得在嵌套集模型上工作成为必要!

实际上,“上级”/父母列表比子代更重要。有什么简单的方法吗?阅读文档/实现djang-mptt是否仍然更快? - anonymous coward
实际上,您需要为 MPTT 添加四个新字段:parentlevelleftright - Daniel Roseman

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

@Vebjorn Ljosa。通过“关联(relation)”一词,我是否正确理解为models.py中的一个类或数据库中的一个表?如果是这样,那么可以说在minion模型中的FK指向了employee模型中的PK。从这里开始,dir(employee)将返回minion_set作为一个参数。我只是想把这个结构弄清楚。 - Tommy Gibbons
@TommyGibbons:正确的(如果我理解你的意思正确的话)。 - Vebjorn Ljosa
@Vebjorn Ljosa:我有一个名为class EmployeeDynamic的类,它有一个指向Employee的外键和一个指向用户(Django管理用户)的外键。使用dir(EmployeeDynamic)无法返回user_set。我正在尝试列出监管者-监管者-员工链中的所有员工。 - Tommy Gibbons
@TommyGibbons:你只会在多对一关系的"多"方看到…_set。如果指向User的外键在EmployeeDynamic中(因此在数据库的app_employeedynamic表中有一个user_id列),则"多"方是User这一侧。在混淆的Django部分之前,你应该绘制一个E-R图并确保你清楚数据库方面的事情。 - Vebjorn Ljosa
混合在令人困惑的Django部分中。好的,明白了。谢谢。 - Tommy Gibbons
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接