childr"/>

关于python:如何使用Django模板渲染树结构(递归)?

关于python:如何使用Django模板渲染树结构(递归)?

How can I render a tree structure (recursive) using a django template?

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

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

将有一些对象rootNode,而childrenNode的列表。 root将在模板的内容中传递。

我已经找到了关于如何实现这一目标的讨论,但是张贴者认为这在生产环境中可能不是很好。

有人知道更好的方法吗?


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

样例代码:

主模板:假设" all_root_elems"是树的一个或多个根的列表

1
2
3
4
5
6
7
<ul>

{%for node in all_root_elems %}
    {%include"tree_view_template.html" %}
{%endfor%}

</ul>

tree_view_template.html渲染嵌套的ulli并使用node模板变量,如下所示:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<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>

我认为规范的答案是:"不要"。

相反,您可能应该做的是在视图代码中分解内容,因此只需遍历模板中的(in | de)凹痕即可。我想我可以通过在循环遍历树时将缩进和缩进附加到列表中,然后将该"旅行"列表发送到模板来做到这一点。 (然后模板将从该列表中插入

  • ,并通过"理解"创建递归结构。)

    我也很确定递归地包含模板文件确实是一种错误的方式...


    我来不及了
    你们所有人都在标签上使用了很多不必要的东西,这就是我递归的方法:

    在"主要"模板中:

    1
    2
    3
    4
    5
    6
    7
    <!-- lets say that menu_list is already defined -->

    <ul>

        {% include"menu.html" %}

    </ul>

    然后在menu.html中:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    {% 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 %}

    这可能比您需要的更多,但是有一个名为" mptt"的django模块-该模块将分层树结构存储在sql数据库中,并包括用于在视图代码中显示的模板。您也许可以在那里找到有用的东西。

    这是链接:django-mptt


    是的,您可以做到。这是一个小把戏
    将文件名作为变量传递到{%include%}:

    1
    2
    3
    {% with template_name="file/to_include.html" %}
    {% include template_name %}
    {% endwith %}

    Django在此确切场景中具有内置的模板帮助器:

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


    我遇到了同样的问题,我写了一个模板标签。我知道那里还有其他这样的标签,但是无论如何我都需要学习制作自定义标签:)我认为效果很好。

    阅读文档字符串以获取用法说明。

    github.com/skid/django-recurse


    更正此:

    root_comment.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    {% 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

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    <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>

    例如-型号:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    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)

    没有人喜欢字典吗?我可能在这里错过了一些东西,但这似乎是设置菜单的最自然的方法。使用键作为条目和值作为链接将其弹出到DIV / NAV中,然后就走了!

    从你的基地

    1
    2
    3
    4
    5
    6
    # Base.html
    <nav>
    {% with dict=contents template="treedict.html" %}
     {% include template %}
    {% endwith %}
    <nav>

    叫这个

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    # 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>
    {{ key }}
    </li>

     {% endif %}
    {% endfor %}

    </ul>

    它没有尝试过默认值或有序命令,也许您已经尝试过?


    我遇到了类似的问题,但是我首先使用JavaScript实现了该解决方案,然后才考虑如何在Django模板中完成相同的工作。

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


    推荐阅读