Как вывести дерево категорий на Django?

Есть модель
class Category(models.Model):
parent = models.ForeignKey('self', null=True, blank=True, on_delete=models.CASCADE, related_name='children')
name = models.CharField(max_length=50)

Нужно построить и вывести дерево в шаблоне! Нужно сделать без django-mptt и других модулей
Подскажите как это сделать и куда копать
В интернете особо инфы не нашел на данную тему. Везде предлагают django-mptt
  • Вопрос задан
  • 1283 просмотра
Пригласить эксперта
Ответы на вопрос 2
sergey-gornostaev
@sergey-gornostaev Куратор тега Django
Седой и строгий
Без MPTT и ему подобных только рекурсией, но это медленно и страшно жрёт ресурсы.
Ответ написан
@javedimka
Хочу сока
Когда-то давно я сделал так. Получив удовлетворение я скачал django-mptt и переделал на mptt

# Example model
class Category(models.Model):
    parent = models.ForeignKey('Category',
                               on_delete=models.CASCADE,
                               verbose_name=_('Parent'),
                               related_name='children',
                               blank=True,
                               null=True)
    title = models.CharField(_('Title'), max_length=64, unique=True)
    slug = models.SlugField(max_length=50)
    objects = CategoryManager()

    
# Manager with method to build tree using directed graph
class CategoryManager(models.Manager):

    def _traverse(self, hierarchy, graph, items):
        for item in items:
            hierarchy.append(item)
            hierarchy.append(self._traverse([], graph, graph[item.title]))
        return hierarchy

    def as_tree(self):
        """Returns FK hierarchy in form of nested lists."""

        qs = super().get_queryset().exclude(
            title='Unassigned'
        ).select_related('parent')

        roots = []
        children = []
        for item in qs:
            roots.append(item) if item.parent is None else children.append(item)

        graph = {item.title: set() for item in qs}

        sorted_children = sorted(children, key=lambda x: x.parent.title)
        grouped = groupby(children, key=lambda x: x.parent.title)

        for title, group in grouped:
            graph[title].update(group)

        return self._traverse([], graph, roots)
    

# To render in template in form of simple nested unordered list use built-in filter:
# https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list

{{ tree|unordered_lsit }}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

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