Перейти к содержанию

Архитектура и устройство иерархий

Модель Level и структура дерева

Модель Level реализует уровень иерархии и базируется на MPTT (Modified Preorder Tree Traversal). В отличие от классических MPTT-деревьев, в Planiqum родительская связь реализована через поле child:

class Level(MPTTModel):
    ...
    child = TreeForeignKey(
        "hierarchy.Level",
        null=True,
        blank=True,
        related_name="mptt_parents",
        on_delete=models.SET_NULL,
    )
    ...
    class MPTTMeta:
        parent_attr = "child"

Это значит: - В MPTT-дереве parent — это child в нашей модели. - Для поиска потомков используйте get_descendants, для поиска предков — get_ancestors.

Методы для работы с родственными уровнями

Для работы с иерархией уровней доступны следующие методы:

  • get_ancestors() — получить список всех предков уровня (по MPTT-структуре).
  • get_descendants() — получить всех потомков уровня (по MPTT-структуре).
  • get_parents() / свойство parents — получить родителей уровня (M2M-связь, может отличаться от MPTT).
  • get_children() — получить дочерние уровни (по MPTT-структуре).

Реальные примеры использования этих методов, а также выводы тестов и пояснения см. в статье Практика работы с иерархиями: реальные примеры и выводы

Работа со связями через parents

Поле parents — это M2M-связь, которая может использоваться для дополнительных бизнес-сценариев (например, для построения альтернативных путей или отображения связей вне MPTT-дерева). В большинстве случаев основная иерархия строится только через поле child.

Dim-таблицы

Для каждого уровня иерархии создаётся отдельная dim-таблица (например, dim_dpu), в которой хранятся элементы этого уровня. Эти таблицы используются для быстрого доступа и агрегации данных. Структура и наполнение dim-таблиц синхронизируются при вызове sync.

Подробнее см. Синхронизация иерархий.

Модель all_parents (устарела)

Внимание: Модель all_parents больше не используется для построения связей между уровнями. Все актуальные связи строятся через MPTT (child) и, при необходимости, через поле parents.

Схема отношений между уровнями (пример)

graph TD
  segment --> business
  business --> brand
  brand --> product_plan_level
  product_plan_level --> dpu
  subcategory --> product_plan_level
  sales_point --> dpu

Выводы

  • Основная иерархия строится через поле child (MPTT).
  • Для поиска потомков используйте get_descendants, для поиска предков — get_ancestors.
  • Связь parents используется для бизнес-логики и может быть пустой.
  • Dim-таблицы используются для хранения элементов уровней и ускорения агрегаций.
  • Модель all_parents устарела и не применяется.