代码之家  ›  专栏  ›  技术社区  ›  anonymous coward

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

  •  3
  • anonymous coward  · 技术社区  · 16 年前

    我使用的是django/python,但这里绝对可以接受伪代码。

    我有一些已经存在的模型 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 mptt,但如果我能保持模型的战术性,并简单地获得更多的功能,它将是值得的。

    2 回复  |  直到 16 年前
        1
  •  2
  •   Bernhard Vallant    16 年前

    你不需要触摸你的模型就可以使用django mptt;你只需要创建一个 parent 在您的模型上,当您注册模型时,django mptt自动为mptt创建所有其他属性: mptt.register(MyModel) .

    不过,如果只需要“上线”层次结构,就不需要嵌套集。更大的性能问题是相反的方向和收集,例如子/叶等,这使得有必要在嵌套集模型上工作!

        2
  •  0
  •   Vebjorn Ljosa    16 年前

    关系数据库不适合这种图形查询,因此您唯一的选择是执行一系列查询。下面是一个递归实现:

    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