Hi!
I have this model:
class Category(models.Model):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', on_delete=models.DO_NOTHING, blank=True, null=True, related_name='children')
def __str__(self):
return self.name
What i want to do is build a tree with categories that have children, for example
Category1
Category1-1
Category1-1-1
Category2
Category2-2
But i want to nested categories until categories that have no children and after that show products related to that category
Is this possible?
Yes it is possible.
However, there’s a lot more to this topic. If you’re working with any kind of tree structure implemented in a relational database, you will want to consider a more robust implementation of your models.
At a minimum, you’ll want to look at django-treebeard, django-mptt, and django-treenode.
Also see the texts and links at:
Thanks!
I was reading about django-treebeard
Can you explain me how i can do what i want using it?
I’d need you to be a lot more specific of what exactly it is you’re trying to accomplish.
I’ve products and each product has a category.
Now, the categories could’ve a parent, so i want to build a tree with the main categories (categories with no parents) and their children (every children could’ve children too)
So the models with django-treebeard is:
class Category(MP_Node):
name = models.CharField(max_length=255)
parent = models.ForeignKey('self', on_delete=models.DO_NOTHING, blank=True, null=True, related_name='children')
So how i can build a tree in my django template with the categories?
I need you to provide more details. What precisely do you mean by “build a tree”? Do you have an idea of the html you’re trying to generate?
I wanna make something with
and - , like:
<!-- Main categories -->
<u>
<li>
Father 1
<!-- Father 1's children -->
<ul>
<li>
First father 1 child
<ul>
<!-- This has to continue until find a child without children -->
</ul>
</li>
</ul>
</li>
</ul>
The idea is get an structure like below
Cool. So it’s a depth-first rendering of a tree.
First, since you’re using an MP_Node, you no longer need a separate parent field.
Given an instance of Category
named category
, category.get_parent()
retrieves the parent of that node, and category.get_children()
retrieves the child nodes.
Rendering this as a tree structure can be done using a recursive use of a template.
For example, you could have a render_nodes.html
template that looks something like this:
<li>{{ category.name }}
<ul>
{% for children in category.get_children %}
{% include "render_nodes.html" with category=children only %}
{% endfor %}
</ul>
</li>
which is then started in your parent template with something like:
<ul>
{% include "render_nodes.html" with category=root_node only %}
</ul>
(Obviously this is illustrative and not definitive.)
Now, as a side note - if this is going to be something rendered frequently, like a menu, you are not going to want to generate this with every request. As written, this is going to generate N+1 queries. You will want to do some sort of caching on that result.