<p>I have a tree structure in memory that I would like to render in HTML using a Django template. </p>

<pre><code>class Node():
  name = "node name"
  children = []
</code></pre>

<p>There will be some object <code>root</code> that is a <code>Node</code>, and <code>children</code> is a list of <code>Node</code>s. <code>root</code> will be passed in the content of the template.</p>

<p>I have found <a href="http://blog.elsdoerfer.name/2008/01/22/recursion-in-django-templates/" rel="noreferrer">this</a> one discussion of how this might be achieved, but the poster suggests this might not be good in a production environment.</p>

<p>Does anybody know of a better way?</p>

[{'answer_id': 32125, 'author': 'Anders Eurenius', 'author_id': 1421, 'author_profile': 'https://Stackoverflow.com/users/1421', 'pm_score': 6, 'selected': True, 'text': '<p>I think the canonical answer is: "Don\'t".</p>\n\n<p>What you should probably do instead is unravel the thing in your <em>view</em> code, so it\'s just a matter of iterating over (in|de)dents in the template. I think I\'d do it by appending indents and dedents to a list while recursing through the tree and then sending that "travelogue" list to the template. (the template would then insert <code>&lt;li&gt;</code> and <code>&lt;/li&gt;</code> from that list, creating the recursive structure with "understanding" it.)</p>\n\n<p>I\'m also pretty sure recursively including template files is really a <em>wrong</em> way to do it...</p>\n'}, {'answer_id': 32857, 'author': 'Community', 'author_id': -1, 'author_profile': 'https://Stackoverflow.com/users/-1', 'pm_score': 4, 'selected': False, 'text': '<p>this might be way more than you need, but there is a django module called \'mptt\' - this stores a hierarchical tree structure in an sql database, and includes templates for display in the view code.  you might be able to find something useful there.</p>\n\n<p>here\'s the link : <a href="https://github.com/django-mptt/django-mptt/" rel="noreferrer">django-mptt</a></p>\n'}, {'answer_id': 41550, 'author': 'Staale', 'author_id': 3355, 'author_profile': 'https://Stackoverflow.com/users/3355', 'pm_score': -1, 'selected': False, 'text': '<p>I had a similar issue, however I had first implemented the solution using JavaScript, and just afterwards considered how I would have done the same thing in django templates.</p>\n\n<p>I used the serializer utility to turn a list off models into json, and used the json data as a basis for my hierarchy.</p>\n'}, {'answer_id': 48262, 'author': 'John', 'author_id': 2168, 'author_profile': 'https://Stackoverflow.com/users/2168', 'pm_score': 3, 'selected': False, 'text': '<p>Django has a built in template helper for this exact scenario:</p>\n\n<p><a href="https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list" rel="noreferrer">https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list</a></p>\n'}, {'answer_id': 957761, 'author': 'disc0dancer', 'author_id': 36047, 'author_profile': 'https://Stackoverflow.com/users/36047', 'pm_score': 3, 'selected': False, 'text': '<p>I had the same problem and I wrote a template tag. I know there are other tags like this out there but I needed to learn to make custom tags anyway :) I think it turned out pretty well.</p>\n\n<p>Read the docstring for usage instructions.</p>\n\n<p><a href="http://github.com/skid/django-recurse" rel="nofollow noreferrer">github.com/skid/django-recurse</a></p>\n'}, {'answer_id': 11644588, 'author': 'Rohan', 'author_id': 229410, 'author_profile': 'https://Stackoverflow.com/users/229410', 'pm_score': 6, 'selected': False, 'text': '<p>Using <code>with</code> template tag, I could do tree/recursive list.</p>\n\n<p>Sample code:</p>\n\n<p>main template: assuming \'all_root_elems\' is list of one or more root of tree</p>\n\n<pre><code>&lt;ul&gt;\n{%for node in all_root_elems %} \n    {%include "tree_view_template.html" %}\n{%endfor%}\n&lt;/ul&gt;\n</code></pre>\n\n<p>tree_view_template.html renders the nested <code>ul</code>, <code>li</code> and uses <code>node</code> template variable as below:</p>\n\n<pre><code>&lt;li&gt; {{node.name}}\n    {%if node.has_childs %}\n        &lt;ul&gt;\n         {%for ch in node.all_childs %}\n              {%with node=ch template_name="tree_view_template.html" %}\n                   {%include template_name%}\n              {%endwith%}\n         {%endfor%}\n         &lt;/ul&gt;\n    {%endif%}\n&lt;/li&gt;\n</code></pre>\n'}, {'answer_id': 12558610, 'author': 'Vladimir', 'author_id': 1153290, 'author_profile': 'https://Stackoverflow.com/users/1153290', 'pm_score': 4, 'selected': False, 'text': '<p>Yes, you can do it. It\'s a little trick, \npassing the filename to {% include %} as a variable:</p>\n\n<pre><code>{% with template_name="file/to_include.html" %}\n{% include template_name %}\n{% endwith %}\n</code></pre>\n'}, {'answer_id': 26045234, 'author': 'Carel', 'author_id': 958580, 'author_profile': 'https://Stackoverflow.com/users/958580', 'pm_score': 1, 'selected': False, 'text': '<p>Does no one like dicts ? I might be missing something here but it would seem the most natural way to setup menus. Using keys as entries and values as links pop it in a DIV/NAV and away you go !</p>\n\n<p>From your base</p>\n\n<pre><code># Base.html\n&lt;nav&gt;\n{% with dict=contents template="treedict.html" %}\n {% include template %}\n{% endwith %}\n&lt;nav&gt;\n</code></pre>\n\n<p>call this</p>\n\n<pre><code># TreeDict.html\n&lt;ul&gt;\n{% for key,val in dict.items %}\n {% if val.items %}\n  &lt;li&gt;{{ key }}&lt;/li&gt;\n  {%with dict=val template="treedict.html" %}\n   {%include template%}\n  {%endwith%}\n {% else %} \n  &lt;li&gt;&lt;a href="{{ val }}"&gt;{{ key }}&lt;/a&gt;&lt;/li&gt;\n {% endif %}\n{% endfor %} \n&lt;/ul&gt;\n</code></pre>\n\n<p>It haven\'t tried the default or the ordered yet perhaps you have ?</p>\n'}, {'answer_id': 33340554, 'author': 'Arthur Sult', 'author_id': 3110300, 'author_profile': 'https://Stackoverflow.com/users/3110300', 'pm_score': 5, 'selected': False, 'text': '<p>I\'m too late.<br>\nAll of you use so much unnecessary <strong><em>with</em></strong> tags, this is how I do recursive:</p>\n\n<p>In the "main" template:</p>\n\n<pre><code>&lt;!-- lets say that menu_list is already defined --&gt;\n&lt;ul&gt;\n    {% include "menu.html" %}\n&lt;/ul&gt;\n</code></pre>\n\n<p>Then in <code>menu.html</code>:</p>\n\n<pre><code>{% for menu in menu_list %}\n    &lt;li&gt;\n        {{ menu.name }}\n        {% if menu.submenus|length %}\n            &lt;ul&gt;\n                {% include "menu.html" with menu_list=menu.submenus %}\n            &lt;/ul&gt;\n        {% endif %}\n    &lt;/li&gt;\n{% endfor %}\n</code></pre>\n'}, {'answer_id': 45398510, 'author': 'meg2mag', 'author_id': 5624832, 'author_profile': 'https://Stackoverflow.com/users/5624832', 'pm_score': 1, 'selected': False, 'text': '<p>correct this:</p>\n\n<h2>root_comment.html</h2>\n\n<pre><code>{% extends \'students/base.html\' %}\n{% load i18n %}\n{% load static from staticfiles %}\n\n{% block content %}\n\n&lt;ul&gt;\n{% for comment in comments %}\n    {% if not comment.parent %}                   ## add this ligic\n    {% include "comment/tree_comment.html" %}\n    {% endif %}\n{% endfor %}\n&lt;/ul&gt;\n\n{% endblock %}\n</code></pre>\n\n<h2>tree_comment.html</h2>\n\n<pre><code>&lt;li&gt;{{ comment.text }}\n    {%if comment.children %}\n        &lt;ul&gt;\n         {% for ch in comment.children.get_queryset %}     # related_name in model\n              {% with comment=ch template_name="comment/tree_comment.html" %}\n                   {% include template_name %}\n              {% endwith %}\n         {% endfor %}\n         &lt;/ul&gt;\n    {% endif %}\n&lt;/li&gt;\n</code></pre>\n\n<h2>for example - model:</h2>\n\n<pre><code>from django.db import models\nfrom django.contrib.auth.models import User\nfrom django.utils.translation import ugettext_lazy as _\n\n\n# Create your models here.\nclass Comment(models.Model):\n    class Meta(object):\n        verbose_name = _(\'Comment\')\n        verbose_name_plural = _(\'Comments\')\n\n    parent = models.ForeignKey(\n        \'self\',\n        on_delete=models.CASCADE,\n        parent_link=True,\n        related_name=\'children\',\n        null=True,\n        blank=True)\n\n    text = models.TextField(\n        max_length=2000,\n        help_text=_(\'Please, your Comment\'),\n        verbose_name=_(\'Comment\'),\n        blank=True)\n\n    public_date = models.DateTimeField(\n        auto_now_add=True)\n\n    correct_date = models.DateTimeField(\n        auto_now=True)\n\n    author = models.ForeignKey(User)\n</code></pre>\n'}]
['https://Stackoverflow.com/questions/32044', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/3154/']