代码之家  ›  专栏  ›  技术社区  ›  David Sykes

如何使用django模板呈现树结构(递归)?

  •  54
  • David Sykes  · 技术社区  · 18 年前

    我在内存中有一个树结构,我想使用Django模板在HTML中呈现它。

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

    root 那是一个 Node children s

    我找到了 this 关于如何实现这一点的讨论,但海报表明,在生产环境中,这可能并不好。

    有人知道更好的方法吗?

    10 回复  |  直到 18 年前
        1
  •  80
  •   the Tin Man    10 年前

    使用 with 模板标签,我可以做树/递归列表。

    示例代码:

    <ul>
    {%for node in all_root_elems %} 
        {%include "tree_view_template.html" %}
    {%endfor%}
    </ul>
    

    tree\u view\u template.html呈现嵌套的 ul , li 和使用 node 模板变量如下所示:

    <li> {{node.name}}
        {%if node.has_childs %}
            <ul>
             {%for ch in node.all_childs %}
                  {%with node=ch template_name="tree_view_template.html" %}
                       {%include template_name%}
                  {%endwith%}
             {%endfor%}
             </ul>
        {%endif%}
    </li>
    
        2
  •  36
  •   cezar Dennis Kioko    6 年前

    我太晚了。
    具有 标记,这是我递归的方式:

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

    然后在 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 %}
    
        3
  •  28
  •   Anders Eurenius    18 年前

    我认为典型的答案是:“不要”。

    相反,你可能应该做的是解开你心中的东西 看法 代码,所以只需在模板中迭代(in | de)凹痕即可。我想我应该通过在树中递归时向列表添加缩进和dedent,然后将“travelogue”列表发送到模板来实现。(然后,模板将插入 <li> </li> 从该列表中,创建递归结构并“理解”它。)

    我也非常确定递归地包含模板文件是一个非常好的方法 错误的

        4
  •  20
  •   dfarrell07    13 年前

    这可能比您需要的多得多,但是有一个名为“mptt”的django模块,它在sql数据库中存储一个层次结构树结构,并包括用于在视图代码中显示的模板。你可能会在那里找到一些有用的东西。

    以下是链接: django-mptt

        5
  •  12
  •   Ashley    12 年前

    将文件名作为变量传递给{%include%}:

    {% with template_name="file/to_include.html" %}
    {% include template_name %}
    {% endwith %}
    
        6
  •  10
  •   cod3monk3y Rodney Lambert    12 年前

    Django有一个内置的模板帮助器,可用于此特定场景:

    https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list

        7
  •  9
  •   the Tin Man    10 年前

    我也有同样的问题,我写了一个模板标签。我知道还有其他类似的标签,但我需要学习如何制作自定义标签:)我认为结果相当不错。

    阅读文档字符串以了解使用说明。

    github.com/skid/django-recurse

        8
  •  1
  •   Carel    11 年前

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

    叫这个

    # 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>
    

    它还没有试过默认的或订购的,也许你试过了?

        9
  •  1
  •   meg2mag    9 年前

    更正此错误:

    {% 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>
    

    例如-模型:

    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)
    
        10
  •  -2
  •   Staale    18 年前

    我有一个类似的问题,但是我首先使用JavaScript实现了解决方案,然后才考虑如何在django模板中完成同样的事情。

    我使用serializer实用程序将模型列表转换为json,并使用json数据作为层次结构的基础。