龙空技术网

递归引用Django模板实现渲染树形结构

一点鑫得 53

前言:

今天兄弟们对“js生成html树状目录教程”都比较关切,咱们都需要了解一些“js生成html树状目录教程”的相关内容。那么小编在网络上收集了一些对于“js生成html树状目录教程””的相关知识,希望同学们能喜欢,同学们快快来了解一下吧!

在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框架来定制树形目录的样式。本文到这里就结束了,希望能帮助到有需要的朋友,也欢迎大家多多关注我的公众号【一点鑫得】,我将持续输出有价值的内容。

标签: #js生成html树状目录教程