Django: Как я моделирую дерево типов гетерогенных данных?

TreeGrid напрямую выходит из Grid, поэтому вы можете использовать аналогичные методы для стилизации TreeGrid.

Предпочтительный способ, например, изменить цвет фона ячейки для использования генератора стилей

Здесь уже есть вопрос об этом с ответом: Как установить цвет фона ячейки в сетке / таблице в Vaadin?

5
задан Corey 17 November 2008 в 18:09
поделиться

3 ответа

Как насчет того, чтобы использовать универсальное отношение из модели, которая будет содержать древовидную структуру к объекту содержания для узла, который это представляет?

from django.db import models
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes import generic

class Node(models.Model):
    content_type = models.ForeignKey(ContentType)
    object_id = models.PositiveIntegerField()
    object = generic.GenericForeignKey('content_type', 'object_id')

Это могло потенциально привести к большому количеству запросов при получении объектов содержания для полного дерева, но существуют пути и средства сокращения количества требуемых запросов.

# Assuming mptt, as I'm not familiar with treebeard's API

# 1 query to retrieve the tree
tree = list(Node.tree.all())

# 4 queries to retrieve and cache all ContentType, A, B and C instances, respectively
populate_content_object_caches(tree)
3
ответ дан 14 December 2019 в 09:03
поделиться

Ваши три типа, вероятно, самыми легкими обработанный как связи FK с фундаментальным деревом.

Дерево может быть однородным - класс MyNode прямой подкласс treebeard.Node. Ваш узел может иметь флаг (Корень, середина, Лист) и FK для A или B или C. Это позволяет Вам некоторую подобную SQL гибкость в запросах экземпляра MyNode.

Это позволяет Вашему дереву расти. Узел может запуститься как тип C (лист) и затем превратиться в тип B (промежуточное звено). Вы изменяете состояние и изменяете FK.

Альтернатива немного более сложна.

class MyA( treebeard.Node ):
    pass

class MyB( treebeard.Node ):
    pass

class MyC( treebeard.Node ):
    pass

В этом случае Вы не можете "превратить" узел. Когда узел запускается как a MyC, и получает детей, необходимо удалить оригинал MyC экземпляр и замена это с a MyB версия, которая имеет новый узел как ребенка. Это не невозможно, но это может быть болезненно.

3
ответ дан 14 December 2019 в 09:03
поделиться

Что ж, многое уже сделано для вас, в некотором смысле, потому что корни, листья и прочее уже изначально идентифицируются API дерева. Вы можете вызывать is_root () и is_leaf () на отдельных узлах, чтобы различать их.

Конечные и промежуточные элементы могут быть одного и того же типа объекта и содержать один и тот же тип данных, с тем, как данные интерпретируются и используются приложение зависит от тестирования is_leaf ().

Корни несколько особенные ... они могут захотеть хранить информацию, относящуюся ко всему дереву, и вам может понравиться простой способ поиска определенных корней и хранения дополнительных данных. Вы можете сделать это с моделью, которая имеет взаимно-однозначную связь с корневым узлом (возможно, с перегруженным методом сохранения и проверкой, чтобы убедиться, что узел, который он указывает на is_root (), прежде чем разрешить сохранение).

В целом я считаю, что для того, чтобы делать то, что вы хотите, вам не нужно сильно увлекаться. Различие, которое вы проводите, уже заключено в концепцию дерева и его API, и вы, вероятно, могли бы реализовать другое поведение с теми же базовыми данными, проверив контекст узла.

1
ответ дан 14 December 2019 в 09:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: