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

发布于 2024-09-07 21:55:04 字数 801 浏览 0 评论 0原文

我使用的是 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,但是如果我能够保持模型完好无损,并且仅仅获得更多功能,那将是值得的。

I'm using Django/Python, but pseudo-code is definitely acceptable here.

Working with some models that already exist, I have Employees that each have a Supervisor, which is essentially a Foreign Key type relationship to another Employee.

Where the Employee/Supervisor hierarchy is something like this:

Any given Employee has ONE Supervisor. That Supervisor may have one or more Employees "beneath", and has his/her own Supervisor as well. Retrieving my "upline" should return my supervisor, his supervisor, her supervisor, etc., until reaching an employee that has no supervisor.

Without going hog-wild and installing new apps to manage these relationships, as this is an existing codebase and project, I'm wondering the "pythonic" or correct way to implement the following functions:

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

I feel like there may be a somewhat simple way to do this with the Django ORM, but if not, I'll take any suggestions.

I haven't thoroughly checked out Django-MPTT, but if I can leave the models in tact, and simply gain more functionality, it would be worth it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

甜点 2024-09-14 21:55:04

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

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

You don't have to touch your models to be able to use django-mptt; you just have to create a parent field on your model, django-mptt creates all the other attributes for mptt automaitcally, when you register your model: mptt.register(MyModel).

Though if you just need the 'upline' hierarchy you wouldn't need nested sets. The bigger performance problem is going the opposite direction and collect eg. children/leaves etc, which makes it necessary to work on a nested set model!

风和你 2024-09-14 21:55:04

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

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

Relational databases are not good for this kind of graph queries, so your only option is to do a bunch of query. Here is a recursive implementation:

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文