我的内存中有一个树结构,我想使用Django模板以HTML呈现。
1 2 3
| class Node():
name ="node name"
children = [] |
将有一些对象root是Node,而children是Node的列表。 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渲染嵌套的ul,li并使用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数据用作层次结构的基础。