处理许多类别或子类别中的django模型的正确方法是什么

时间:2013-05-12 14:07:10

标签: django django-models categories django-mptt

我不确定为此任务设计模型的最佳方法。搜索周围表明我需要使用像Django-MPTT这样的东西。

我正在创建一个列表应用程序,其中任何“项目”都可以列在多个类别下。在任何类别中,我都需要能够查询匹配的“项目”。

一个例子应该说明我想要的更好一点。

我有一个 Item1 ,要分配给两个子类别。

TopLevel1
   --- Sublevel1
   --- Sublevel2
           -----> Item1

TopLevel1
   --- Sublevel1
          ------> Item1
   --- Sublevel2

有人能建议如何构建模型/关系吗?我目前的实施

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


class Item(TimeStampedModel):
    name = models.TextField(null=False, blank=False)
    categories = models.ManyToManyField(Category)

感觉不是正确的解决方案吗?

1 个答案:

答案 0 :(得分:1)

这就是我看到的......

您的模型似乎很接近,m2m似乎合适,但您的图表看起来更像:

Item1
    ---> TopLevel1 (accessed through `categories`)
        ---> SubLevel1 (accessed through `Category.children`, see below)
        ---> SubLevel2 (accessed through `Category.children`, see below)

你的模特看起来更像

class Category(models.Model):
    name = models.CharField(max_length=128) # `blank` is false by default
    parent = models.ForeignKey('self', null=True, blank=True, related_name='children') # by giving this field a nice `related_name`, we can easily access the linked categories

class Item(TimeStampedModel):
    name = models.TextField() # `null` and `blank` are false by default
    categories = models.ManyToManyField(Category, null=True, blank=True, related_name='items') 

现在,如果你有一个项目,并希望获得它的顶级类别,你可以循环item.categories.all()

{% for category in item.categories.all %}
    Top Level: {{ category.name }}
{% endfor %}

要访问子级别类别,请在每个children.all()

中循环浏览category
{% for category in item.categories.all %}
    Top Level: {{ category.name }}
    {% for child in category.children.all %}
        Sub Level: {{ child.name }}
        Parent: {{ child.parent.name }}
    {% endfor %}
{% endfor %}

您还可以获取类别中的所有项目

{% for item in category.items.all %}
    Item: {{ item.name }}
{% endfor %}

或者如果您处于顶级类别

{% for child in category.children.all %}
    {{ child.name }}
    {% for item in child.items.all %}
        Item: {{ item.name }}
    {% endfor %}
{% endfor %}

并且

category_one = Category.objects.create('category one')
category_two = Category.objects.create('category two')
item_one = Item.objects.create('item one')

您可以通过Category上的add categoriesrelated manager Item

item_one.categories.add(category_one, category_two)

或者您可以通过Item

上的相关管理员items add Category {/ 1}}
category_one.items.add(item_one)