Categories are essential for any website because it is easy for users to access content sorted by categories. Categories may have their subcategories, and subcategories may also have subcategories and so on. So in this post, I’ll explain how to implement nested categories in a Django project. You can create categories with Django Admin Panel and then associate it with content like an article or post, So let’s get started.
Jump into the code
Let’s implement categories for blog posts, consider my_posts app in the project, add following models in it
Next, we’ll use category in Post model as a foreign key.
So with Category being a foreign key in Post model, a category can be associated with post.
Open the terminal and change the current working directory to one that contains manage.py then run following migration commands.
Now we make some Category object from the interactive shell so open Django interactive shell by typing following command in terminal.
Then in shell, you can create categories as illustrated below
Now we’ll add categories with Django Admin Panel, so add following code to admin.py
then run the server by
Now go to admin panel from your browser, you’ll see category there.
Now we add some main categories, by main categories I mean the categories having a null parent. Go to categories and click “Add Category” and add the category like in the image below.
Now to illustrate the nested categories add one more main category say “python”, now add a category “news” as a subcategory of “python”, you have to select “python” as the parent category of “news”, like in the image below.
Now for sake of well understanding add one more category “2017” having “news” as parent category like in the image below.
Now the categories we’ve created are showed as follow.
You may be wondering how ‘– >’ are appended after categories ( which is useful in distinguishing between same-named subcategories of a different parent at any level ), this is since we have defined the str method in Category model.
Let’s add a post to illustrate how to associate a category with it, so go to the home in admin panel then go to post and click ‘add post’ button.
As you can see in the image, we have added the post in python > news > 2017. Next, we have to add URL pattern for the category, so go to urls.py and add the following line in urlpatterns list.
Now in views.py add the following function.
Note that the last element of the category_slug list in show_category could either be a Post object or a category object,
For example the parameter hierarchy may be ‘/python/news’ or it may be ‘python/news/2017/instagram-makes-a-move-to-python-3/’ in former case the last element of category_slug would be a category object but in later case it is a Post object, so in for loop tracing categories with hierarchical relation so if the last element be a Post object then it will be rendered with “postDetail.html” template, otherwise if it be a Category object then it will be rendered with “categories.html” template.
In context dictionary, ‘breadcrumbs’ are there because you may want to have the breadcrumb in your post detail page.
Add following code in “categories.html”.
The CSS framework used is Zurb’s Foundation 6 you may use bootstrap as well.
Next, add following code snippet inside the postDetail.html template to implement breadcrumbs in post detail page ( you should add it above post’s title ).
So breadcrumbs in post detail page would look like in the image below.
And our Category pages would look like images below
Note that we have only a subcategory in Python/news and no post so only subcategory there. But in ‘2017’ there is no subcategory and a simple post which showed in the image below.
You may be wondering about the cover_image attribute used in template code and hence reflected in card view of the post in above photo, the cover_photo is a field in Post model and for brevity, I did not include the cover_photo attribute in code. If you have any queries regarding it then comment below.
Although this approach is not most efficient because we are making many database queries, but for small websites and blogs this approach is good to go. If you are working on some projects like a news website or e-commerce website which contain many level of nested categories then you may want to find a comparatively efficient way to implement category with Modified Preorder Tree Traversal (MPTT), there is Django package available for it, read a post on how to implement categories with django-mptt here.
If you have any query let me know in the comments below.
Happy coding :)
comments powered by Disqus