Represent a tree of objects in Django template(在 Django 模板中表示对象树)
问题描述
我有一个 Django 模型,它有一个同一个类的外键,有效地制作了一棵树:
I have a Django model which has a ForeignKey to the same class, effectively making a tree:
class Tag(models.Model):
name = models.CharField(max_length=50)
parent = models.ForeignKey('self', blank=True, null=True)
在 Django shell (./manage.py shell
) 中使用递归,我可以轻松地将树表示为纯文本:
Playing around with a recursive in the Django shell (./manage.py shell
), I am easily able to represent the tree as plain text:
def nodes(parent, level):
children = Tag.objects.filter(parent=parent)
for c in children:
spaces = ""
for i in xrange(0,level):
spaces+=" "
print "%s%s" % (spaces,c.name)
nodes(c.pk,level+1)
nodes(None,0)
我不确定的是如何将整个树放入 Django 模板中.我创建了一个自定义模板标记来简化此操作,但我不知道如何将数据传递给模板以轻松遍历树以在模板中显示.这是基本的模板标签.
What I am unsure of is how to get the entire tree into a Django template. I've created a custom template tag to make this easier, but I can't figure out how to pass the data to the template to easily iterate over the tree for display in a template. Here's the basic template tag.
@register.inclusion_tag("core/tags.html")
def render_tags(**kwargs):
tags = Tag.objects.all()
return {"tags":tags}
我知道以上内容非常基本,我只是不知道从哪里开始.我认为如果 Tag 类有一个函数来获取它的子类可能会更容易,所以我也有这个类:
I know the above is very basic, I just am not sure where to go from here. I thought it might be easier if the Tag class had a function to get its children, so I also have on the class:
def children(self):
return Tag.objects.filter(parent=self.pk)
我在那里使用self.pk
,那么树的根就是rootTag=Tag()
,因为它没有保存,所以没有pk,rootTag.children()
会找到任何没有父标签的标签,然后这些标签中的任何一个都可以继续调用它们的 children()
函数.但是就像我说的那样,我不知道如何将其转换为某种单一的数据结构以传递给我的模板.
I use self.pk
there, then the root of the tree is simply rootTag=Tag()
, since it has no pk since it is not saved, rootTag.children()
will find any Tags which do not have a parent Tag, and any of these tags can then just continue to have their children()
function called. But like I said, I do not know how to turn this into a single data structure of some sort to pass to my template.
想法?我想我可能想建立一种字典,我只是无法在这里跟进.
Thoughts? I think I probably want to build a kind of dict, I'm just not able to follow through here.
推荐答案
正如 Jprofitt 提到的 DjangoMPTT 是实现目标的好方法你要.
As Jproffitt mentionned it Django MPTT is a nice way to achieve what you want.
使用它,您可以在模板中递归访问子实例,像这样:
Using it, you can then access children instance, recursively, in your template, like this:
{% load mptt_tags %}
<h1>Tags</h1>
<ul>
{% recursetree tags %}
<li>{{ node.name }}
{% if not node.is_leaf_node %}
<ul>
{{ children }}
</ul>
{% endif %}
</li>
{% endrecursetree %}
</ul>
我的一个项目使用了它,它易于设置和使用.
I have it for one of my projects and it's easy to set up and to use.
如果您不想使用专用应用程序,我认为这些解决方案可能会奏效(未经测试):
If you don't want to use a dedicated app, I think these solution might work (untested):
# yourapp/tags_list.html
<ul>
{% for tag in tags %}
<li>{{ tag.name }}</li>
{% if tag.children.exists %}
{% with tag.children.all as tags %}
{% include "yourapp/tags_list.html" %}
{% endwith %}
{% endif %}
{% endfor %}
</ul>
这样,模板就应该递归调用自己,直到没有更多儿童标签.此解决方案需要您在标签模型中指定相关名称:
This way, the template should just call himself recursively until there is no more children tags. This solution needs that you specify a related name in your Tag model :
parent = models.ForeignKey('self', blank=True, null=True, related_name="children")
但是,请注意,与使用 MPTT 相比,这些解决方案将涉及更多的数据库查询.
However, be careful, these solution will involve more database queries than using MPTT.
这篇关于在 Django 模板中表示对象树的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:在 Django 模板中表示对象树
基础教程推荐
- 筛选NumPy数组 2022-01-01
- Dask.array.套用_沿_轴:由于额外的元素([1]),使用dask.array的每一行作为另一个函数的输入失败 2022-01-01
- 如何让 python 脚本监听来自另一个脚本的输入 2022-01-01
- 在 Python 中,如果我在一个“with"中返回.块,文件还会关闭吗? 2022-01-01
- 使用PyInstaller后在Windows中打开可执行文件时出错 2022-01-01
- 如何在海运重新绘制中自定义标题和y标签 2022-01-01
- 何时使用 os.name、sys.platform 或 platform.system? 2022-01-01
- Python kivy 入口点 inflateRest2 无法定位 libpng16-16.dll 2022-01-01
- 用于分类数据的跳跃记号标签 2022-01-01
- 线程时出现 msgbox 错误,GUI 块 2022-01-01