Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django categories, sub-categories and sub-sub-categories

Tags:

django

I have a simple category model:

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

At first, my data seemed to need only categories and subcategories, but I realized that there are some cases where I still want to sub-sub-categorize.

I want my urls to be category/subcategory/sub-subcategory

I was thinking about how to implement this but I am not sure, since my url pattern matching looks like this:

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

Basically only allowing a single sub-category, since my view method accepts these two parameters.

What is the best way to handle this?

like image 375
AlexBrand Avatar asked Feb 29 '12 01:02

AlexBrand


People also ask

What is categories and sub categories?

In Document360, categories and subcategories are used to organize and display groups of similar topic articles, acting as folders that contain groups of related content.

What is a sub subcategory?

: a category that is a subdivision of a larger category : a secondary category grouping the books into the appropriate categories and subcategories A new subcategory of vodkas, which provide a contrast to the "tasteless" aspect of this spirit, are the flavored vodkas …— Alexis Bespaloff.


1 Answers

What about unlimited levels? At urls.py:

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

And at directory/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)
    ...

Don't forget to add unique_together = ('slug', 'parent',) to Category.Meta, otherwise you are doomed.

[update]

could I just query the db with category_slugs[-1] and if the obtained category has no children, we know its a leaf category, otherwise, we know it has subcategories and we show them? – alexBrand

@alexBrand: consider the following hypothetical URLs:

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

If you think such scenario is possible, then IMHO a simpler test (without the whole hierarchy) is not enough.

What are your real concerns regarding the proposed solution? At the end of the loop, the variable category will hold the correct category_slugs[-1], and you will have the whole hierarchy available in categories. Don't worry about performance, my best advice is: don't try to optimize an elegant solution before profiling (you will be surprised).

like image 129
Paulo Scardine Avatar answered Sep 30 '22 06:09

Paulo Scardine