Django+zTree构建组织架构树的方法


Posted in Python onAugust 21, 2019

树,因其清晰明了的展现形式而被广泛的使用

日常的开发过程中我们需要经常与“树”打交道,例如公司的组织架构树、服务器的项目归属树,管理后台侧边树等等,本篇文章介绍关于树的两个内容

  • 多功能的前端树插件zTree
  • Django中关于树的model设计

zTree

zTree是一个开源的依靠JQuery实现的多功能树插件,具有性能优异、配置灵活、功能强大的特点

之前的系列前端插件文章已经多次介绍过将前端插件引入自己项目中的方法,这里就不赘述了,如有问题也可以参考文章末尾给出的Demo代码,在引入JS/CSS之后只需要如下代码即可构建一颗树

<ul id="treeDemo" class="ztree"></ul>
<script>
 var setting = {
 data: {
 simpleData: {
  enable: true
 }
 }
 };
 var zNodes = [
 {id: 1, pId: 0, name: "OPS-COFFEE ", open: true},
 {id: 2, pId: 1, name: "运营部", open: true},
 {id: 3, pId: 1, name: "市场部", open: true},
 {id: 4, pId: 1, name: "综合部", open: true},
 {id: 5, pId: 2, name: "产品部", open: true},
 {id: 6, pId: 2, name: "技术部", open: true},
 {id: 7, pId: 3, name: "销售部", open: true},
 {id: 8, pId: 4, name: "人事部", open: true},
 {id: 9, pId: 4, name: "财务部", open: true},
 ];
 $.fn.zTree.init($("#treeDemo"), setting, zNodes);
</script>

$.fn.zTree.init 初始化树,这里需要三个参数,第一个参数是加载树结构的Jquery对象, setting 为ztree的各种配置参数, zNodes 为ztree的具体数据

zTree的配置采用json的格式,按照配置类型分为了界面配置 view ,数据配置 data ,编辑配置 edit ,复选框配置 check ,异步加载配置 async 以及各种回调函数配置 callback ,配置丰富且强大

zTree支持两种数据模式,简单数据模式和标准数据模式,简单数据模式就像我们上边例子中这样的数据结构,而标准数据模式就需要将数据构造成复杂的JSON嵌套格式,像下边这样

var zNodes = [{
 "name": "OPS-COFFEE",
 "open": true,
 "children": [
 {
  "name": "运营部",
  "open": true,
  "children": [
  {"name": "产品部","open": true},
  {"name": "技术部","open": true}
  ]
 },
 {
  "name": "市场部",
  "open": true,
  "children": [
  {"name": "销售部","open": true}
  ]
 },
 {
  "name": "综合部",
  "open": true,
  "children": [
  {"name": "人事部","open": true},
  {"name": "财务部","open": true}
  ]
 }
 ]
}];

标准模式数据结构复杂但父子关系清晰,简单模式数据则相反,示例中我们使用了简单数据模式,需要配置simpleData的 enable 属性为true

完成以上配置后可以看到页面效果如下

Django+zTree构建组织架构树的方法 

Django

既然前端页面已经能够正常展示树了,后端就只需要返回前端对应的数据格式即可,Django中最简单的方式就是使用Foreignkey的自关联,模型设计如下:

class Department(models.Model):
    name = models.CharField(
        max_length=128, unique=True, verbose_name='名称')
    parent = models.ForeignKey(
        'self', on_delete=models.PROTECT, db_constraint=False,
        null=True, blank=True, verbose_name='父部门')

ForeignKey第一个参数用 self 就表示自关联,自己关联自己,还有两个Foreignkey的重要参数解释如下:

on_delete:控制当外键引用的对象被删除时指定的SQL约束行为

  • CASCADE:级联删除,当你删除数据时与之关联的也会删除
  • PROTECT:保护模式,当你删除数据时会抛出 ProtectedError 的错误
  • SET_NULL:设置为空,当你删除数据时外键字段被设置为空,前提是有设置 null=True, blank=True
  • SET_DEFAULT:设置默认值,当你删除数据时外键字段设置为默认值,前提是有设置 default 值
  • DO_NOTHING:什么也不做,但这可能会导致你在调用数据时报错

SET:设置一个指定的自定义实例,官方案例如下

from django.conf import settings
from django.contrib.auth import get_user_model
from django.db import models
def get_sentinel_user():
 return get_user_model().objects.get_or_create(username='deleted')[0]
class MyModel(models.Model):
 user = models.ForeignKey(
 settings.AUTH_USER_MODEL,
 on_delete=models.SET(get_sentinel_user),
 )

这个案例的意思是当删除外键字段user有关联时调用 get_sentinel_user 方法,这个方法会返回一个username为deleted的实例

db_constraint:控制是否在数据库中为此外键创建约束,默认为True。在数据库中创建外键约束是 数据库规范中明令禁止 的行为,那么我们可以设置 db_constraint 为 False 从而不在数据库层面创建约束,但同样可以使用Django为Foreignkey提供的各种关联查询

接下来可以通过如下代码将数据库中的数据转成ztree所能使用的简单模式数据并返回

def tree(request):
 mList = Department.objects.all()
 _data = [
 {
  'id': x.id,
  'name': x.name,
  'pId': x.parent.id if x.parent else 0, 'open': 1
 } for x in mList
 ]
 return render(request, 'tree.html', {'data': _data})

注意在前端使用时需要用 {{data|safe}} 的方式,添加 |safe 主要是因为Django为了安全默认会对HTML、JS等语法标签进行转义,但我们所传给前端的数据不希望转义可以通过添加 |safe 来实现

完整Demo

文章源码已上传至Github,除了以上基础代码外还包含下拉框加载树等功能,

源码地址如下:https://github.com/ops-coffee/demo/tree/master/tree

Django+zTree构建组织架构树的方法 

总结

以上所述是小编给大家介绍的Django+zTree构建组织架构树的方法,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
Python命令行参数解析模块getopt使用实例
Apr 13 Python
详解Python中dict与set的使用
Aug 10 Python
Django ORM框架的定时任务如何使用详解
Oct 19 Python
python使用xpath中遇到:到底是什么?
Jan 04 Python
解决matplotlib库show()方法不显示图片的问题
May 24 Python
python实现旋转和水平翻转的方法
Oct 25 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
Dec 15 Python
python实现动态创建类的方法分析
Jun 25 Python
Python pip 安装与使用(安装、更新、删除)
Oct 06 Python
如何查看Django ORM执行的SQL语句的实现
Apr 20 Python
Python select及selectors模块概念用法详解
Jun 22 Python
Python的代理类实现,控制访问和修改属性的权限你都了解吗
Mar 21 Python
python的移位操作实现详解
Aug 21 #Python
基于Python的微信机器人开发 微信登录和获取好友列表实现解析
Aug 21 #Python
Python+OpenCv制作证件图片生成器的操作方法
Aug 21 #Python
Python数据可视化实现正态分布(高斯分布)
Aug 21 #Python
django自带serializers序列化返回指定字段的方法
Aug 21 #Python
应用OpenCV和Python进行SIFT算法的实现详解
Aug 21 #Python
Python Django 添加首页尾页上一页下一页代码实例
Aug 21 #Python
You might like
Windows 下的 PHP-PEAR 安装方法
2010/11/20 PHP
php实现utf-8和GB2312编码相互转换函数代码
2013/02/07 PHP
ThinkPHP验证码使用简明教程
2014/03/05 PHP
Codeigniter检测表单post数据的方法
2015/03/21 PHP
百万级别知乎用户数据抓取与分析之PHP开发
2015/09/28 PHP
php实现不通过扩展名准确判断文件类型的方法【finfo_file方法与二进制流】
2017/04/18 PHP
取得元素的左和上偏移量的方法
2014/09/17 Javascript
JavaScript学习笔记之JS函数
2015/01/22 Javascript
Jquery异步提交表单代码分享
2015/03/26 Javascript
基于javascript实现样式清新图片轮播特效
2016/03/30 Javascript
JS实现touch 点击滑动轮播实例代码
2017/01/19 Javascript
简单实现js选项卡切换效果
2017/02/09 Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
2017/07/11 Javascript
关于jquery form表单序列化的注意事项详解
2017/08/01 jQuery
js+html5生成自动排列对话框实例
2017/10/09 Javascript
微信小程序promsie.all和promise顺序执行
2017/10/27 Javascript
解决option标签selected=&quot;selected&quot;属性失效的问题
2017/11/06 Javascript
基于Bootstrap下拉框插件bootstrap-select使用方法详解
2018/08/07 Javascript
详解Vue一个案例引发「内容分发slot」的最全总结
2018/12/02 Javascript
深入理解nodejs搭建静态服务器(实现命令行)
2019/02/05 NodeJs
vue swipeCell滑动单元格(仿微信)的实现示例
2020/09/14 Javascript
[02:41]《西雅图我们来了》2015国际邀请赛出征全记录
2015/07/23 DOTA
跟老齐学Python之永远强大的函数
2014/09/14 Python
Python开发常用的一些开源Package分享
2015/02/14 Python
Python读取和处理文件后缀为.sqlite的数据文件(实例讲解)
2017/06/27 Python
python 计算数组中每个数字出现多少次--“Bucket”桶的思想
2017/12/19 Python
python3+PyQt5实现自定义流体混合窗口部件
2018/04/24 Python
关于阿里云oss获取sts凭证 app直传 python的实例
2019/08/20 Python
Python pathlib模块使用方法及实例解析
2020/10/05 Python
开放系统互连参考模型
2016/06/29 面试题
大学生入党自我鉴定
2013/10/31 职场文书
函授毕业自我鉴定
2013/12/19 职场文书
优秀教师的感人事迹
2014/02/04 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
幼儿园教师心得体会范文
2016/01/21 职场文书
2019年自助餐厅创业计划书模板
2019/08/22 职场文书