效果图如下:
基础环境介绍:
python3.8.6、Django4.1,Win10,pycharm2020.1.5
首先去EasyUI官网下载免费版,拿到框架基础JS及CSS文件。Jquery EasyUI下载
按照官网给的前端源代码,按照JSS和CSS文件路径在官网下载的文件夹中找到对应的资源放到自己的代码中去。
官网给出了TreeGrid的数据格式样例在treegrid_data1.json中
仿照官网给出的数据格式,我们传到前端数据也需要进行格式转换。由于我们在Python后端中常用的数据结构为列表或字典,下面我以列表为源数据进行转换为例。
源数据:
list_data = [
{"id": 1,
"name": "C",
"size": "",
"date": "02/19/2010",
"parent_id": None
},
{
"id": 2,
"name": "Program Files",
"size": "120 MB",
"date": "03/20/2010",
"parent_id": 1
},
{
"id": 21,
"name": "Java",
"size": "",
"date": "01/13/2010",
"parent_id": 2
},
{
"id": 211,
"name": "java.exe",
"size": "142 KB",
"date": "01/13/2010",
"parent_id": 21
},
{
"id": 212,
"name": "jawt.dll",
"size": "5 KB",
"date": "01/13/2010",
"parent_id": 21
},
{
"id": 22,
"name": "MySQL",
"size": "",
"date": "01/13/2010",
"parent_id": 2
},
{
"id": 221,
"name": "my.ini",
"size": "10 KB",
"date": "02/26/2009",
"parent_id": 22
}, {
"id": 222,
"name": "my-huge.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
}, {
"id": 223,
"name": "my-large.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
},
{
"id": 3,
"name": "eclipse",
"size": "",
"date": "01/20/2010",
"parent_id": 1
},
{
"id": 31,
"name": "eclipse.exe",
"size": "56 KB",
"date": "05/19/2009",
"parent_id": 3
}, {
"id": 32,
"name": "eclipse.ini",
"size": "1 KB",
"date": "04/20/2010",
"parent_id": 3
}, {
"id": 33,
"name": "notice.html",
"size": "7 KB",
"date": "03/17/2005",
"parent_id": 3
}
]
转换方法:
def list_to_tree(data, parent_id=None):
"""将列表数据转换为树形结构"""
tree = []
for item in data:
if item.get('parent_id') == parent_id:
children = list_to_tree(data, item['id'])
if children:
item['children'] = children
# 下面是在每个子节点中,加入该元素,TreeGrid会将数据初始状态设置为折叠的
item.update({"state": "closed"})
tree.append(item)
return tree
转换后的结果:
[
{
"id": 1,
"name": "C",
"size": "",
"date": "02/19/2010",
"parent_id": null,
"children": [
{
"id": 2,
"name": "Program Files",
"size": "120 MB",
"date": "03/20/2010",
"parent_id": 1,
"children": [
{
"id": 21,
"name": "Java",
"size": "",
"date": "01/13/2010",
"parent_id": 2,
"children": [
{
"id": 211,
"name": "java.exe",
"size": "142 KB",
"date": "01/13/2010",
"parent_id": 21
},
{
"id": 212,
"name": "jawt.dll",
"size": "5 KB",
"date": "01/13/2010",
"parent_id": 21
}
],
"state": "closed"
},
{
"id": 22,
"name": "MySQL",
"size": "",
"date": "01/13/2010",
"parent_id": 2,
"children": [
{
"id": 221,
"name": "my.ini",
"size": "10 KB",
"date": "02/26/2009",
"parent_id": 22
},
{
"id": 222,
"name": "my-huge.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
},
{
"id": 223,
"name": "my-large.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
}
],
"state": "closed"
}
],
"state": "closed"
},
{
"id": 3,
"name": "eclipse",
"size": "",
"date": "01/20/2010",
"parent_id": 1,
"children": [
{
"id": 31,
"name": "eclipse.exe",
"size": "56 KB",
"date": "05/19/2009",
"parent_id": 3
},
{
"id": 32,
"name": "eclipse.ini",
"size": "1 KB",
"date": "04/20/2010",
"parent_id": 3
},
{
"id": 33,
"name": "notice.html",
"size": "7 KB",
"date": "03/17/2005",
"parent_id": 3
}
],
"state": "closed"
}
],
"state": "closed"
}
]
再直接将结果返回给前端就完美解决了。
下面是前后端完整代码
前端代码:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Basic TreeGrid - jQuery EasyUI Demo</title>
<link rel="stylesheet" type="text/css" href="../../static/CSDN_GridTree/easyui.css">
<link rel="stylesheet" type="text/css" href="../../static/CSDN_GridTree/icon.css">
<link rel="stylesheet" type="text/css" href="../../static/CSDN_GridTree/demo.css">
<script type="text/javascript" src="../../static/CSDN_GridTree/jquery.min.js"></script>
<script type="text/javascript" src="../../static/CSDN_GridTree/jquery.easyui.min.js"></script>
</head>
<body>
<div style="margin:20px 0;"></div>
<table title="Folder Browser" class="easyui-treegrid" style="width:700px;height:250px"
data-options="
{# 下面放入自己返回数据的Url地址 #}
url: '/CSDN_GridTree/data/',
method: 'get',
rownumbers: true,
idField: 'id',
treeField: 'name',
fit:true,
">
<thead>
<tr>
<th data-options="field:'name'" width="220">Name</th>
<th data-options="field:'size'" width="100" align="right">Size</th>
<th data-options="field:'date'" width="150">Modified Date</th>
</tr>
</thead>
</table>
</body>
</html>
后端代码:
import json
from django.http import JsonResponse
from django.shortcuts import render
list_data = [
{"id": 1,
"name": "C",
"size": "",
"date": "02/19/2010",
"parent_id": None
},
{
"id": 2,
"name": "Program Files",
"size": "120 MB",
"date": "03/20/2010",
"parent_id": 1
},
{
"id": 21,
"name": "Java",
"size": "",
"date": "01/13/2010",
"parent_id": 2
},
{
"id": 211,
"name": "java.exe",
"size": "142 KB",
"date": "01/13/2010",
"parent_id": 21
},
{
"id": 212,
"name": "jawt.dll",
"size": "5 KB",
"date": "01/13/2010",
"parent_id": 21
},
{
"id": 22,
"name": "MySQL",
"size": "",
"date": "01/13/2010",
"parent_id": 2
},
{
"id": 221,
"name": "my.ini",
"size": "10 KB",
"date": "02/26/2009",
"parent_id": 22
}, {
"id": 222,
"name": "my-huge.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
}, {
"id": 223,
"name": "my-large.ini",
"size": "5 KB",
"date": "02/26/2009",
"parent_id": 22
},
{
"id": 3,
"name": "eclipse",
"size": "",
"date": "01/20/2010",
"parent_id": 1
},
{
"id": 31,
"name": "eclipse.exe",
"size": "56 KB",
"date": "05/19/2009",
"parent_id": 3
}, {
"id": 32,
"name": "eclipse.ini",
"size": "1 KB",
"date": "04/20/2010",
"parent_id": 3
}, {
"id": 33,
"name": "notice.html",
"size": "7 KB",
"date": "03/17/2005",
"parent_id": 3
}
]
def list_to_tree(data, parent_id=None):
"""将列表数据转换为树形结构"""
tree = []
for item in data:
if item.get('parent_id') == parent_id:
children = list_to_tree(data, item['id'])
if children:
item['children'] = children
# 下面是在每个子节点中,加入该元素,TreeGrid会将数据初始状态设置为折叠的
item.update({"state": "closed"})
tree.append(item)
return tree
# 跳转到前端页面
def CSDN_GridTree_list(request):
return render(request, 'CSDN_Tree.html')
# 返回树形数据结果
def CSDN_GridTree(request):
tree_data = list_to_tree(list_data)
return JsonResponse(tree_data,safe=False)
需要注意的事项:
1、必须要有根节点,且根节点的父节点处应为空
2、一条数据不能对应多条父级,因此要注意每条数据的id最好是唯一的。(这里有些业务场景可能会需要这个功能,后续找到合适的处理方式再来完善)