如何使用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呈现嵌套的ulli并使用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数据作为我的层次结构的基础。