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

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

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

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

我发现 这个曾经讨论过如何实现这一点,但是海报暗示这在生产环境中可能不太好。

有人知道更好的办法吗?

37454 次浏览

我认为标准答案是: “不要”。

相反,您可能应该做的是解开 风景代码中的内容,所以这只是在模板中迭代(in | de)凹痕的问题。我认为我可以在遍历树的同时将缩进和缩进添加到列表中,然后将“ travelogue”列表发送到模板中。(然后模板将从该列表中插入 <li></li>,创建“理解”它的递归结构。)

我也非常肯定递归地包含模板文件实际上是一种 错了的方式来做到这一点..。

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

这是链接: Django-mptt

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

我使用序列化工具将一个关闭模型的列表转换为 json,并使用 json 数据作为层次结构的基础。

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

阅读 docstring 以获得使用说明。

Github.com/skid/django-recurse

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

示例代码:

Main template: 假设‘ all _ root _ elems’是一个或多个树根的列表

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

Tree _ view _ template.html 呈现嵌套的 ulli并使用 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>

你可以的,这是个小把戏, 将文件名作为变量传递给{% include% } :

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

没有人喜欢独裁者吗?我可能遗漏了一些东西,但这似乎是设置菜单最自然的方式。使用键作为条目和值作为链接弹出它在一个 DIV/NAV 和你走!

从你的基地

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

它还没有尝试过默认值或者命令,也许你已经尝试过了?

我来晚了。
你们都用了很多不必要的 (附图)标签,这就是我做递归的方法:

在“ main”模板中:

<!-- 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 %}

纠正一下:

Root _ comments. 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 _ comments. 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)