我在内存中有一个树结构,我希望使用Django模板在HTML中呈现。
class Node():
name = "node name"
children = []
某些对象root
是Node
,而children
是Node
的列表。 root
将在模板的内容中传递。
我已经找到了this关于如何实现这一目标的讨论,但是海报表明这在生产环境中可能并不好。
有人知道更好的方法吗?
答案 0 :(得分:67)
使用with
模板标签,我可以做树/递归列表。
示例代码:
主模板:假设'all_root_elems'是树的一个或多个根的列表
<ul>
{%for node in all_root_elems %}
{%include "tree_view_template.html" %}
{%endfor%}
</ul>
tree_view_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>
答案 1 :(得分:27)
我认为规范的答案是:“不要”。
你应该做的事情是解开 view 代码中的东西,所以这只是在模板中迭代(in | de)凹痕的问题。我想我会通过在列表中附加缩进和dedents来实现它,同时通过树递归然后将“travelogue”列表发送到模板。 (然后模板将从该列表中插入<li>
和</li>
,创建递归结构并“理解”它。)
我也非常确定递归包含模板文件实际上是错误的方式...
答案 2 :(得分:20)
这可能比你需要的更多,但是有一个名为'mptt'的django模块 - 它在sql数据库中存储一个分层树结构,并包含在视图代码中显示的模板。你或许可以在那里找到有用的东西。
这是链接:django-mptt
答案 3 :(得分:12)
我太晚了) 所有人都使用了这么多不必要的 和 标签,这就是我的回复方式:
在主模板中:
<!-- 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 %}
答案 4 :(得分:11)
是的,你可以做到。这是一个小技巧, 将文件名作为变量传递给{%include%}:
{% with template_name="file/to_include.html" %}
{% include template_name %}
{% endwith %}
答案 5 :(得分:9)
Django为这个确切的场景提供了一个内置的模板助手:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list
答案 6 :(得分:8)
我有同样的问题,我写了一个模板标签。我知道还有其他类似的标签,但我还是需要学习制作自定义标签:)我认为结果非常好。
阅读文档字符串以获取使用说明。
答案 7 :(得分:0)
没有人喜欢dicts吗?我可能在这里遗漏了一些东西,但这似乎是设置菜单最自然的方式。使用键作为条目和值作为链接在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>
它没有尝试过默认或订购但也许你有吗?
答案 8 :(得分:0)
纠正这个:
{% 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 %}
<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)
答案 9 :(得分:-2)
我有一个类似的问题,但是我首先使用JavaScript实现了解决方案,然后考虑了如何在django模板中完成相同的操作。
我使用序列化工具将模型中的列表转换为json,并使用json数据作为我的层次结构的基础。