基于前后端分离的父子id思考

449 阅读2分钟

前后端分离之后,数据渲染交给了前端,数据自然交给了后端,自然关于数据的格式也是如此的,那么今天我们聊聊常见的父子id渲染思路。

使用场景

在整个开发的需求当中,经常会遇到这样的树状数据结构的需求,比如:文件目录,公司架构等等,这些需求共性的特点,就是基于一张数据表并且有父子关系,于是有一种很常见的表设计方式:

id父idname
10董事长
21财务部长
32财务出纳

这样通过父id字段表述自己的父组件是谁,形成父子结构,通过查询数据的父id来查询当前数据的所有子元素,通过id为0表示他是树结构的根节点。

基于前端对这样类型的数据渲染,往往需要两个数据格式:

常规格式

{
    "error_message": "查询成功",
    "data": [
        {
            "id": 1,
            "pid": 0,
            "name": "董事长"
        },
        {
            "id": 2,
            "pid": 1,
            "name": "财务部长"
        },
        {
            "id": 3,
            "pid": 2,
            "name": "财务出纳"
        },
        
    ],
    "code": 1
}

嵌套格式

但是基于前端树状ui组件的需求可能需要的是嵌套格式

{
    "error_message": "查询成功",
    "data": [
        {
            "id": 1,
            "pid": 0,
            "name": "董事长",
            "children": [
                {
                    "id": 2,
                    "pid": 1,
                    "name": "财务部长"
                     "children": [
                         {
                            "id": 3,
                            "pid": 2,
                            "name": "财务出纳"
                         }
                     ]
                }
            ]
        }
    ],
    "code": 1
}

实现方式

所以基于上面的第二种数据需求方式,服务的就需要基于父子id去构建嵌套结构, 介绍一种刚刚见到的方式,注意用来Python自动的设置默认值(setdefault)和更新(update)方法和深浅拷贝的知识点。

data = [
    {'id': 1, 'parent_id': 0, "name": "node"},
    {'id': 2, 'parent_id': 1, "name": "node-1-1"},
    {'id': 3, 'parent_id': 1, "name": "node-1-2"},
    {'id': 4, 'parent_id': 2, "name": "node-2-1"},
    {'id': 5, 'parent_id': 4, "name": "node-4-1"},
    {'id': 6, 'parent_id': 5, "name": "node-5-1"},
    {'id': 7, 'parent_id': 5, "name": "node-5-2"},
    
]
​
def list_tree(data,parent_tag,child_tag,children_label,root_point):
    """
    data 数据
    parent_tag 标识父元素的键
    child_tag 标识子元素的键
    children_label 嵌套的键
    root_point 根节点的标识父元素对应的值
    """
    res = {}
    for v in data:
        res.setdefault(v[parent_tag],v).update(v)
        res.setdefault(v[child_tag],{}).setdefault(children_label,[]).append(res.get(v[parent_tag],v))
    if res:
        return res[root_point][children_label]
    else:
        return res
​
if __name__ == "__main__":
    list_tree(data,"id","parent_id","children",0)

返回结果就不输出了,大家运行代码即可,当然还有其他方法,欢迎各位大佬多多指点。