【问题标题】:Parent/Child(ren) Hierarchy / "Nested Sets", in Python/Django父/子(ren)层次结构/“嵌套集”,在 Python/Django 中
【发布时间】:2011-03-09 19:18:08
【问题描述】:

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

使用一些已经存在的模型,我有Employees,每个模型都有一个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,但如果我可以保留模型并简单地获得更多功能,那将是值得的。

【问题讨论】:

    标签: python django parent-child hierarchy


    【解决方案1】:

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

    但如果您只需要“上线”层次结构,则不需要嵌套集。更大的性能问题是朝着相反的方向发展并收集例如。孩子/叶子等,这使得有必要在嵌套集合模型上工作!

    【讨论】:

    • 实际上,“上线”/父母名单比孩子重要得多。什么是简单的方法?阅读文档/实现 djang-mptt 会更快吗?
    • 其实mptt需要四个新字段:parentlevelleftright
    【解决方案2】:

    关系型数据库不适合这种图形查询,所以你唯一的选择就是做一堆查询。这是一个递归实现:

    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
    

    【讨论】:

    • 我需要在get_upline() 中添加一个空supervisor 的检查吗?我正在想象到达根目录时会发生异常或发生的事情。我错了吗?
    • Vebjorn,你能解释一下self.minion_set.all() 的来源吗?
    • @TommyGibbons,这是一个名为“minion”的关系的 Django RelatedManager
    • @Vebjorn Ljosa。通过 relation 我是否正确理解为 models.py 中的类或 db 中的表?如果是这样的话,说minion 中的FK 指向employee 中的PK 是否公平。从这里dir (employee) 将返回minion_set 作为一个参数。我只是想弄清楚这个结构。
    • @TommyGibbons:正确(如果我理解正确的话)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-23
    • 1970-01-01
    相关资源
    最近更新 更多