2012-02-29 147 views
4

我有一个简单的分类模型:Django的类别,子类别和子子类别

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

起初,我的数据似乎只需要类别和子类别,但我意识到,有一些情况下,我仍然希望子分类。

我想我的网址是类别/子/子子类别

我在思考如何实现这一点,但我不知道,因为我的URL模式匹配看起来是这样的:

url(r'^business/(?P<parent>[-\w]+)/(?P<category_name>[-\w]+)$', 'directory.views.show_category'), 

基本上只允许一个子类别,因为我的view方法接受这两个参数。

处理这个问题的最佳方法是什么?

回答

12

什么是无限级?在urls.py:

url(r'^business/(?P<hierarchy>.+)/', 'directory.views.show_category') 

而在目录/ views.py:

def show_category(request, hierarchy): 
    category_slugs = hierarchy.split('/') 
    categories = [] 
    for slug in category_slugs: 
     if not categories: 
      parent = None 
     else: 
      parent = categories[-1] 
     category = get_object_or_404(Category, slug=slug, parent=parent) 
     categories.append(category) 
    ... 

不要忘记添加unique_together = ('slug', 'parent',)到Category.Meta,否则你注定。

[更新]

我能不能查询与category_slugs分贝[-1],如果所获得的类别有没有孩子,我们知道它的叶类,否则,我们知道它有子类,我们给他们看? - alexBrand

@alexBrand:考虑以下假设网址:

/business/manufacture/frozen/pizza/ 
/business/restaurant/italian/pizza/ 
/business/delivery-only/italian/pizza/ 
/business/sports/eating-contest/pizza/ 

如果你认为这样的情况是可能的,那么恕我直言,一个简单的测试(不整个层次)是不够的。

您对建议的解决方案有什么疑问?在循环结束时,变量类别将保存正确的category_slugs[-1],并且您将在categories中提供整个层级结构。不要担心性能,我最好的建议是:不要在分析之前优化一个优雅的解决方案(你会感到惊讶)。

+0

我可以用category_slugs [-1]查询数据库,如果获得的类别没有子类,我们知道它是一个叶子类别,否则,我们知道它有子类别,我们显示它们? – AlexBrand 2012-02-29 13:43:29

+0

@alexBrand:查看更新的答案。 – 2012-02-29 19:42:23

+0

你是完全正确的。我没有想到在不同类别中使用相同的子类别名称的可能性。 – AlexBrand 2012-02-29 20:54:23