如何使用Django模板呈现树结构(recursion)?
我在内存中有一个树结构,我想使用Django模板在HTML中呈现。
class Node(): name = "node name" children = []
会有一些对象的root
是一个Node
,而children
是一个Node
的列表。 root
将被传递到模板的内容中。
我已经find了这样一个如何实现的讨论,但是海报表明这在生产环境中可能不是很好。
有人知道更好的方法吗?
我认为这个规范的答案是:“不要”。
你可能应该做的是在你的视图代码中解开这个东西,所以这只是在模板中迭代(in | de)凹痕的问题。 我想通过在树中recursion时将缩进和缩进附加到列表中,然后将该“移动”列表发送到模板来实现。 (模板会从列表中插入<li>
和</li>
,创buildrecursion结构并“理解”它)。
我也很确定recursion包含模板文件是一个真正的错误的方式来做到这一点…
使用模板标签,我可以做树/recursion列表。
示例代码:
主模板:假设“all_root_elems”是树的一个或多个根的列表
<ul> {%for node in all_root_elems %} {%include "tree_view_template.html" %} {%endfor%} </ul>
tree_view_template.html呈现嵌套的ul
, li
并使用node
模板variables,如下所示:
<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>
这可能比你需要的多,但是有一个名为“mptt”的django模块 – 它在sql数据库中存储了一个分层树结构,并且包含了在视图代码中显示的模板。 你可能会find一些有用的东西。
这里是链接: django-mptt
是的,你可以做到。 这是一个小技巧,将文件名作为variables传递给{%include%}:
{% with template_name="file/to_include.html" %} {% include template_name %} {% endwith %}
对于这个确切的场景,Django有一个内置的模板助手:
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#unordered-list
我有同样的问题,我写了一个模板标签。 我知道有这样的其他标签,但我需要学习定制标签无论如何:)我认为它非常好。
阅读文档string的使用说明。
github.com/skid/django-recurse
我太迟了)你们所有人都用标签这么多,这是我如何回复:
在主模板中:
<!-- 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 %}
没有人喜欢口水? 我可能会错过这里的东西,但它似乎是设置菜单最自然的方式。 使用键作为条目和值作为链接popup一个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>
它没有尝试默认或有序的,也许你有?
纠正这一点:
root_comment.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_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)
我有一个类似的问题,但是我第一次使用JavaScript实现解决scheme,后来考虑如何在django模板中做同样的事情。
我使用序列化工具将模型中的列表closures为json,并使用json数据作为我的层次结构的基础。