Отобразить много-много категорий в записи (тегирование) и сохранить иерархическое дерево / представление категорий? - PullRequest
1 голос
/ 22 июня 2010

Я пишу записи для кросс-браузерных ошибок / обходных путей.Мне бы хотелось, чтобы в главном представлении отображалось иерархическое дерево, начинающееся с первичных категорий и спускающееся в более конкретные категории:

css
    layout
       float
       position
    specificity

js
    dom
html
    object
    embed

Допустим, я хочу подать запись, чтобы она отображалась под обоими floatи position, потому что ошибка в этой записи является комбинацией двух.

Моя схема категории такова:

category_id    category_name    parent_id

При этом моя строка float будет выглядеть так:

10   float  9

9 (parent_id) указывает на мою layout строку:

9    layout 8

8 указывает на мою css строку:

8    css  null

Question 1: Поскольку записи могут иметь много категорий, мне нужна таблица для сопоставления этих отношений, верно?В настоящее время у меня есть модель Entries and Categories, поэтому мне нужна третья таблица?Он будет содержать category_id и entry_id.

Question 2: Как сохранить дерево / иерархическое представление категорий, если я делаю много категорий для одной записи?Я немного сбит с толку, потому что поначалу мне казалось, что с одной категорией все немного проще, но, поскольку у меня есть несколько, я не совсем понимаю, как мне начать это.

Модели пока:

class Bug( models.Model ):
    name = models.CharField( max_length=100 )
    slug = models.SlugField(unique=True)
    excerpt = models.TextField()
    excerpt_markdown = models.TextField( editable=False, blank=True )
    summary = models.TextField()
    summary_markdown = models.TextField(editable=False, blank=True)
    #workaround = models.TextField()
    #workaround_markdown = models.TextField(editable=False, blank=True)
    date_added = models.DateTimeField()
    poster = models.ForeignKey(User)

class Category ( models.Model ):
    name = models.CharField( max_length=100 )
    parent_id = models.IntegerField()

1 Ответ

2 голосов
/ 22 июня 2010

Вам не нужен конкретный третий стол. ManyToManyField в Django - то, что вам нужно здесь для связи между Entires и Categories - автоматически заботится о присоединяющейся таблице, если вы не хотите специально контролировать ее (например, если вам нужно хранить дополнительные данные в соединении).

Как вы заметили в своем комментарии, django-mptt - лучший выбор для хранения иерархических отношений категорий.Как только вы это сделаете, нет ничего особенно сложного в том, что у вас есть связь ManyToMany между записями и категориями - вам просто нужно показать отдельное дерево для каждой категории, в которой находится запись:

{% for category in my_entry.categories.all %}
    {{ category.show_tree }}
{% endfor %}

где show_tree - это метод, который рисует дерево для этой категории, которое вам нужно определить, вдоль строк ответа на ваш последний вопрос.

Редактировать

Основная проблема с моделями, которые у вас есть сейчас, заключается в том, что нет никаких отношений.По крайней мере, вам понадобятся отношения ManyToMany между ошибкой и категорией и отношение ForeignKey от категории к себе (т. Е. От одной категории к себе).Добавление MPTT к модели категории поверх этого - через поля level, tree_id, left и right, которые будут автоматически добавлены django-mptt, - облегчит объединение всех родителей или детей в одинgo.

class Bug( models.Model ):
    name = models.CharField( max_length=100 )
    slug = models.SlugField(unique=True)
    excerpt = models.TextField()
    excerpt_markdown = models.TextField( editable=False, blank=True )
    summary = models.TextField()
    summary_markdown = models.TextField(editable=False, blank=True)
    #workaround = models.TextField()
    #workaround_markdown = models.TextField(editable=False, blank=True)
    date_added = models.DateTimeField()
    poster = models.ForeignKey(User)
    categories = models.ManyToManyField('Category')

class Category ( models.Model ):
    name = models.CharField( max_length=100 )
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children')

mptt.register(Category)

Теперь, учитывая один элемент Bug, вы можете получить связанные с ним категории с помощью mybug.categories.all(), а для каждой категории вы можете получить своих предков с помощью category.get_ancestors().См. mptt docs для получения дополнительной информации о том, что вы можете сделать, особенно в тегах шаблонов для отображения деревьев.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...