将多个类别映射到条目(标记),并保留分类树/类别视图?

时间:2010-06-22 18:27:21

标签: django schema

我正在编写跨浏览器错误/解决方法的条目。我希望主视图能够呈现一个从主要类别开始并逐渐下降到更具体类别的层次结构树:

css
    layout
       float
       position
    specificity

js
    dom
html
    object
    embed

假设我要提交一个条目并将其显示在floatposition下,因为此条目中的错误是两者的组合。

我的类别架构是这样的:

category_id    category_name    parent_id

这样,我的float行将是:

10   float  9

9(parent_id)指向我的layout行:

9    layout 8

8指向我的css行:

8    css  null

Question 1:由于条目可能有很多类别,我需要一张表来映射这些关系,对吗?我目前有一个条目和类别模型,所以我需要第三个表?它将包含category_identry_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 个答案:

答案 0 :(得分:2)

您不需要特定的第三张表。 Django的ManyToManyField - 你想在这里得到的是Entires和Categories之间的关系 - 自动处理连接表,除非你特别想要控制它(例如,如果你需要在连接上存储额外的数据)。

正如您在评论中所认识到的那样,django-mptt是存储类别层次关系的最佳选择。一旦你完成了这一点,你就不会特别难以在条目和类别之间建立一个ManyToMany关系 - 你只需要为条目所在的每个类别显示一个单独的树:

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

其中show_tree是为该类别绘制树的方法 - 您需要根据上一个问题的答案来定义。

修改

现在你拥有模型的主要问题是没有关系。至少,你需要Bug和Category之间的ManyToMany关系,以及从Category到它自己的ForeignKey关系(即从一个类别到它自己)。将MPTT添加到类别模型之上 - 通过leveltree_idleftright字段(将由django-mptt自动添加)将使其更容易让所有的父母或孩子一气呵成。

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,尤其是提供的用于显示树的模板标记。