I have a tree structure for Categories. Categories with a Foreign key that is referring to itself.
class Category(MetaData):
parent = models.ForeignKey('self', blank=True, null=True, verbose_name='parent category', on_delete=models.CASCADE)
name = models.CharField(max_length=255)
description = models.TextField()
Because I don't know the depth of the categories tree(can't use for) I need to use a recursive function:
def cat_for_parents(self, cat_obj):
...
if cat_obj.parent_id:
p = cat_obj.parent
...
self.cat_for_parents(p)
But how I implement the function in the template to get something like this(to theoretically infinite recursive loop):
<ul>
<li>CategoryA
<ul>
<li>SubCategA1
<ul>
<li> Subcateg Subcateg B1
<ul>
<li> Subcateg SubCateg C1>
<li> Subcateg SubCateg C2>
<ul>
<li> Subcateg Subcateg B2>
.............
I used
inclusion_tag
to solve this.Example:
model
:views.py
:template
:Custom tag function:
tree_structure.html
:How it works:
Getting the categories without any parent and send them to template. In template we use a for loop to render categories one by one and before going to next category to render, you check if that category hast any subs. If there was any subs for that category, you will pass the category to your custom template tag and there you will get all the sub categories for that given category and pass it to another template file to render them but before finishing it, check for that category to see if that one has sub categories too or not and if it does just call custom function again before u finish rendering the first one. it will goes till there is no more category and sub categories and at the end passes a complete template with all the sub categories for the first passed category to the main template to render before other categories.
I couldn't test this code myself so there might be small issues.
Also check the documentation for custom template tags: Custom template tags and filters