How can I render a tree structure (recursive) usin

2020-01-27 02:23发布

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

class Node():
  name = "node name"
  children = []

There will be some object root that is a Node, and children is a list of Nodes. root will be passed in the content of the template.

I have found this one discussion of how this might be achieved, but the poster suggests this might not be good in a production environment.

Does anybody know of a better way?

标签: python django
10条回答
别忘想泡老子
2楼-- · 2020-01-27 02:30

Yes, you can do it. It's a little trick, passing the filename to {% include %} as a variable:

{% with template_name="file/to_include.html" %}
{% include template_name %}
{% endwith %}
查看更多
We Are One
3楼-- · 2020-01-27 02:32

correct this:

root_comment.html

{% extends 'students/base.html' %}
{% load i18n %}
{% load static from staticfiles %}

{% block content %}

<ul>
{% for comment in comments %}
    {% if not comment.parent %}                   ## add this ligic
    {% include "comment/tree_comment.html" %}
    {% endif %}
{% endfor %}
</ul>

{% endblock %}

tree_comment.html

<li>{{ comment.text }}
    {%if comment.children %}
        <ul>
         {% for ch in comment.children.get_queryset %}     # related_name in model
              {% with comment=ch template_name="comment/tree_comment.html" %}
                   {% include template_name %}
              {% endwith %}
         {% endfor %}
         </ul>
    {% endif %}
</li>

for example - model:

from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext_lazy as _


# Create your models here.
class Comment(models.Model):
    class Meta(object):
        verbose_name = _('Comment')
        verbose_name_plural = _('Comments')

    parent = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        parent_link=True,
        related_name='children',
        null=True,
        blank=True)

    text = models.TextField(
        max_length=2000,
        help_text=_('Please, your Comment'),
        verbose_name=_('Comment'),
        blank=True)

    public_date = models.DateTimeField(
        auto_now_add=True)

    correct_date = models.DateTimeField(
        auto_now=True)

    author = models.ForeignKey(User)
查看更多
贪生不怕死
4楼-- · 2020-01-27 02:33

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.

here's the link : django-mptt

查看更多
beautiful°
5楼-- · 2020-01-27 02:39

I'm too late.
All of you use so much unnecessary with tags, this is how I do recursive:

In the "main" template:

<!-- lets say that menu_list is already defined -->
<ul>
    {% include "menu.html" %}
</ul>

Then in menu.html:

{% for menu in menu_list %}
    <li>
        {{ menu.name }}
        {% if menu.submenus|length %}
            <ul>
                {% include "menu.html" with menu_list=menu.submenus %}
            </ul>
        {% endif %}
    </li>
{% endfor %}
查看更多
爱情/是我丢掉的垃圾
6楼-- · 2020-01-27 02:41

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.

I used the serializer utility to turn a list off models into json, and used the json data as a basis for my hierarchy.

查看更多
Evening l夕情丶
7楼-- · 2020-01-27 02:46

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 !

From your base

# Base.html
<nav>
{% with dict=contents template="treedict.html" %}
 {% include template %}
{% endwith %}
<nav>

call this

# TreeDict.html
<ul>
{% for key,val in dict.items %}
 {% if val.items %}
  <li>{{ key }}</li>
  {%with dict=val template="treedict.html" %}
   {%include template%}
  {%endwith%}
 {% else %} 
  <li><a href="{{ val }}">{{ key }}</a></li>
 {% endif %}
{% endfor %} 
</ul>

It haven't tried the default or the ordered yet perhaps you have ?

查看更多
登录 后发表回答