Tree structure of parent relationship of child elements in django templates

How to implement a tree structure in django templates without using django-mptt.

I have a model.

class Person(TimeStampedModel): name = models.CharField(max_length=32) parent = models.ForeignKey('self', null=True, blank=True, related_name='children') 

Now I want..

  Parent Child 1 subchild 1.1 subchild 1.2 nextsubchild 1.2.1 Child 2 Child 3 

there names must be clicked to show their profile.

+4
source share
4 answers

from a Django while loop question and

http://docs.djangoproject.com/en/dev/howto/custom-template-tags/#inclusion-tags

 # view.py @register.inclusion_tag('children.html') def children_tag(person): children = person.children.all() return {'children': children} # children.html <ul> {% for child in children %} <li> <a href="{{ child.get_absolute_url }}">{{ child }}</a></li> {% if child.children.count > 0 %} {% children_list child %} {% endif %} {% endfor %} </ul> # your template {% children_tag parent %} 
+9
source

I just finished implementing this. I need a tree structure for sub navigation, but I didn’t want to do anything strange with recursive templates.

The solution I implemented is very simple: I just recursively examine (in my case, a general helper function) and align the hierarchical structure into a simple list. Then in my template, I just use the for loop to iterate through the list.

Each item in the list can be one of three: "in", object, or "out". In my case, I create a series of ul li elements in the view, so when I encounter "in", I create a new ul, when I encounter "out", I close ul. Otherwise, I throw out the item.

My template code is as follows:

  {% for item in sub_nav %} {% if item == "in" %} <ul> {% else %} {% if item == "out" %} </ul> </li> {% else %} <li> <a href='{{item.full_url}}'>{{item.name}}</a> {% if item.leaf %} </li> {% endif %} {% endif %} {% endif %} {% endfor %} 

The code in the helper function looks like this:

 def get_category_nav(request,categories=None): """Recursively build a list of product categories. The resulting list is meant to be iterated over in a view""" if categories==None: #get the root categories categories = ProductCategory.objects.filter(parent=None) categories[0].active=True else: yield 'in' for category in categories: yield category subcats = ProductCategory.objects.select_related().filter(parent=category) if len(subcats): category.leaf=False for x in get_category_nav(request,subcats): yield x else: category.leaf=True yield 'out' 

Using these fragments, you should be able to create any hierarchical tree that you want, without any recursion in the template and keeping all the logic in the view.

I know that there was already an accepted answer for this, but I thought that I would send the equipment in case this helps someone else.

+11
source

These are great answers, but I put it together a bit and put it in the actual model.

 class RecursiveThing(models.Model): name = models.CharField(max_length=32) parent = models.ForeignKey('self', related_name='children', blank=True, null=True) def as_tree(self): children = list(self.children.all()) branch = bool(children) yield branch, self for child in children: for next in child.as_tree(): yield next yield branch, None 

And then in your template:

 <ul> {% for thing in things %} {% for branch, obj in thing.as_tree %} {% if obj %} <li>{{ obj.name }} {% if branch %} <ul> {% else %} </li> {% endif %} {% else %} {% if branch %} </ul> {% endif %} {% endif %} {% endfor %} {% endfor %} </ul> 
+2
source

It is very simple

All you have to do in your view is to get all the objects:

 people = Person.objects.all() 

Then in your template:

 {% for person in people %} <li>- {{person.name}} </li> {% for child in person.children.all %} <ul>* {{child.nom}} </ul> {% endfor %} </li> {% endfor %} 
0
source

Source: https://habr.com/ru/post/1342762/


All Articles