![](https://news.xinpengboligang.com/upload/keji/c9792c5ccd7e3938e7c60584c9826388.jpeg)
在web開發中,經常需要顯示展示層次化的數據,比如文件目錄、產品分類目錄、組織結構等,這是典型的樹形數據結構。Django是web開發中使用非常廣泛的框架,那麼你知道怎麼使用Django模塊渲染樹形數據結構嗎?本文將會給出答案。
我們知道編程語言大多都有遞歸調用的能力,遍歷樹形數據結構往往都需要進行遞歸調用,而Django使用模板引擎進行頁面的渲染,而樹形結構數據往往都是從數據庫動態獲取的,嵌套的層級深度並不是確定的,因此Django模板必須能夠做到類似遞歸調用的能力才能做到渲染樹形數據結構。幸運地的是,Django模板引擎是支持遞歸引用的,接下來我們通過一個簡單的例子來詳細介紹Django模板如何通過include指令遞歸引用模塊文件,最終渲染出樹形目錄結構。這裡不會從頭介紹Django如何創建項目,隻針對關鍵文件進行講解,因此需要讀者具備一定的Django基礎。
準備樹形結構數據
一般情況下,樹形結構數據都是從數據庫動態生成的,為了突出重點,這裡僅給出最終的樹形數據結構示例。我們把它寫在views.py文件中,tree_list為樹形數據,列表中的每一項包含id、name、parent_id、children,其中children為子節點,包含同樣的結構,可以一直嵌套下去。
from django.shortcuts import render
# Create your views here.
def index(request):
"""
tree_list數據結構形式:[
{
"id": xx,
"name": xxx,
"parent_id": xxx,
"children": [
{
"id": xx,
"name": xxx,
"parent_id": xxx,
"children": []
}
]
},
...
]
"""
context = {}
context["tree_list"] = [{
"id": 2,
"name": "類別A",
"parentId": None,
"children": [
{
"id": 8,
"name": "類別A1",
"parentId": 2,
"children": [
{
"id": 137,
"name": "類別A11",
"parentId": 8,
}
]
},
{
"id": 221,
"name": "類別A2",
"parentId": 2,
}
]
},
{
"id": 52,
"name": "類別B",
"parentId": None,
"children": [
{
"id": 54,
"name": "類別B1",
"parentId": 52,
"fileCount": 10,
"children": [
{
"id": 55,
"name": "類別B11",
"parentId": 54,
"children": [
{
"id": 56,
"name": "類別B111",
"parentId": 55,
"children": [
{
"id": 57,
"name": "類別B1111",
"parentId": 56,
"children": [
{
"id": 58,
"name": "類別B11111",
"parentId": 57,
}
]
}
]
}
]
}
]
}
]
},
{
"id": 53,
"name": "類別C",
"parentId": None,
"children": [
{
"id": 80,
"name": "類別C1",
"parentId": 53,
},
{
"id": 224,
"name": "類別C2",
"parentId": 53,
}
]
},
{
"id": 69,
"name": "類別D",
"parentId": None,
"children": [
{
"id": 70,
"name": "類別D1",
"parentId": 69,
"children": [
{
"id": 4,
"name": "類別D11",
"parentId": 70,
"children": [
{
"id": 51,
"name": "類別D111",
"parentId": 4,
}
]
}
]
},
{
"id": 91,
"name": "類別D2",
"parentId": 69,
},
{
"id": 102,
"name": "類別D3",
"parentId": 69,
},
{
"id": 113,
"name": "類別D4",
"parentId": 69,
},
{
"id": 121,
"name": "類別D5",
"parentId": 69,
},
{
"id": 136,
"name": "類別D6",
"parentId": 69,
},
{
"id": 140,
"name": "類別D7",
"parentId": 69,
"children": [
{
"id": 142,
"name": "類別D71",
"parentId": 140,
}
]
}
]
}
]
return render(request, 'demo/index.html', context)
模板文件
templates/demo目錄下創建兩個模板文件index.html、children.html,index.html文件中關鍵部分的代碼為for循環指令包圍的部分,它負責遍歷上面提到的tree_list列表的每一項,也就是數據結構的第一級目錄,如果列表中的某一項children內容不為空,則執行指令{% include 'demo/children.html' with tree_list=item.children %},它的意思就相當於render(request, 'demo/children.html', item.children),也就是說插入當前項的子節點作為數據源渲染出的頁面。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>django模板</title>
<style>
.flex {
display: flex;
}
.list-unstyled ul {
padding-left: 0;
list-style: none;
}
.tree {
padding: 0.3rem 1rem ;
background-color: #f5f5f5;
color: #333;
}
.tree li li {
padding-left: 0.5rem;
}
.tree li::before {
content: '\0203A';
opacity: 0;
}
.tree .expand::before {
content: '\0203A';
opacity: 1;
}
</style>
</head>
<body>
<h3>Django模板渲染樹形目錄示例</h3>
<div class="flex">
<div class="tree list-unstyled">
<ul>
{% for item in tree_list %}
{% if item.children %}
<li class="expand">
{{ item.name }}
{% include 'demo/children.html' with tree_list=item.children %}
</li>
{% else %}
<li>
{{ item.name }}
</li>
{% endif %}
{% endfor %}
</ul>
</div>
<div class="right"></div>
</div>
</body>
</html>
接下來看children.html,它看起來和前面是很類似的,隻不過這裡include指令中使用的模板就是自己本身,傳入的數據源逐層剝離出子節點,這就是和編程語言的遞歸是一樣的了,最終所有children節點都完全遍歷到並渲染出最終的html頁面,這樣就實現了渲染樹形結構數據。
<ul>
{% for item in tree_list %}
{% if item.children %}
<li class="expand">
{{ item.name }}
{% include 'demo/children.html' with tree_list=item.children %}
</li>
{% else %}
<li>
{{ item.name }}
</li>
{% endif %}
{% endfor %}
</ul>
最後渲染出的樹形目錄如下, index.html中寫了一點css改變了默認的樣式,你可以根據自己的需要使用成熟的UI框架來定制樹形目錄的樣式。本文到這裡就結束了,希望能幫助到有需要的朋友,也歡迎大傢多多關註我的公眾號【一點鑫得】,我將持續輸出有價值的內容。
![](https://news.xinpengboligang.com/upload/keji/198b152acdf12db0ee2bfca5bb20fd0a.jpeg)