Иерархия Parent / Child (ren) / "вложенные множества" - PullRequest
3 голосов
/ 29 июня 2010

Я использую Django / Python, но здесь определенно допустим псевдокод.

Работая с некоторыми уже существующими моделями, у меня есть Employee s, у каждой из которых есть Supervisor, что по сути является отношением типа внешнего ключа к другой Employee.

В тех случаях, когда иерархия «Сотрудник / Руководитель» выглядит примерно так:

У любого сотрудника есть ОДИН руководитель.У этого Супервайзера может быть один или несколько Сотрудников «ниже», и у него также есть собственный Супервайзер.Получение моего «вышестоящего» должно вернуть моего руководителя, его руководителя, ее руководителя и т. Д. До достижения сотрудника, у которого нет руководителя.

Без лишних усилий и установки новых приложений для управления этими отношениями, так как это существующая кодовая база и проект, я задаюсь вопросом "питонический" или правильный способ реализации следующих функций:

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 голосов
/ 29 июня 2010

Вам не нужно прикасаться к своим моделям, чтобы использовать django-mptt;вам просто нужно создать поле parent в вашей модели, django-mptt автоматически создает все остальные атрибуты для mptt, когда вы регистрируете вашу модель: mptt.register(MyModel).

Хотя, если вам нужна иерархия верхнего уровня, вам не понадобятся вложенные множества.Большая проблема производительности идет в противоположном направлении и собирать, например.children / leaves и т. д., что делает необходимым работать с моделью вложенного множества!

0 голосов
/ 29 июня 2010

Реляционные базы данных не подходят для такого рода графических запросов, поэтому единственный вариант - выполнить несколько запросов.Вот рекурсивная реализация:

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
...