使用django-treebeard实现树类型存储与编辑
前言
其实之前做很多项目都有遇到跟树相关的功能,以前都是自己实现的,然后前端很多UI组件库都有Tree组件,套上去就可以用。
不过既然用 Django 了,还是得充分发挥一下生态的优势,但是我找了半天,也就这个 treebeard 能用,其他要不停更了要不就功能很拉,没有可视化编辑树的功能。
难道Django已经没落了?
效果
以这个汽车改装项目为例
实现以下效果,可以拖动节点进行编辑

安装
安装依赖
pdm add django-treebeard
将 treebeard 添加到 INSTALLED_APPS
定义model
继承 MP_Node 类型就可以
from treebeard.mp_tree import MP_Node
class CaseCategory(MP_Node):
name = models.CharField('类别名称', max_length=100)
node_order_by = ['name']
def __str__(self):
return '改装类别: {}'.format(self.name)
class Meta:
db_table = 'car_case_category'
verbose_name = '改装类别'
verbose_name_plural = verbose_name
配置 admin
需要继承 TreeAdmin 才能实现可视化的树编辑
from treebeard.admin import TreeAdmin
@admin.register(CaseCategory)
class CaseCategoryAdmin(TreeAdmin):
form = movenodeform_factory(CaseCategory)
list_display = ['name', 'depth']
search_fields = ['name']
初始化数据
可以使用代码把初始化的Tree数据导入
(事实上是因为不先导入初始化数据,admin界面连个添加按钮都没有……估计是bug)
def seed_data_treebeard():
from apps.car.models import CaseCategory
get = lambda node_id: CaseCategory.objects.get(pk=node_id)
root = CaseCategory.add_root(name='车衣')
node = get(root.pk).add_child(name='亮面/光面')
node = get(root.pk).add_child(name='磨砂/哑光')
root = CaseCategory.add_root(name='改色')
get(root.pk).add_child(name='纯色系')
get(root.pk).add_child(name='渐变色')
get(root.pk).add_child(name='定制彩绘')
root = CaseCategory.add_root(name='改装')
get(root.pk).add_child(name='轮毂')
get(root.pk).add_child(name='刹车')
get(root.pk).add_child(name='避震')
root = CaseCategory.add_root(name='省心提')
这样打开admin界面就可以看到了
算是能用吧
写个接口
然后我再写个简单的接口,基于 django-ninja
(实际上这些代码是 DjangoStarter 自动生成的)
from typing import List
from django.shortcuts import get_object_or_404
from ninja import Router, ModelSchema
from django_starter.http.response import responses
router = Router(tags=['case_category'])
class CaseCategoryOut(ModelSchema):
class Meta:
model = CaseCategory
fields = ['id', 'path', 'depth', 'numchild', 'name', ]
@router.get('/', response=List[CaseCategoryOut], url_name='car/case_category/list')
def list_items(request):
qs = CaseCategory.objects.all()
return qs
结果出来的数据是这样(省略部分数据)
{
"code": 200,
"data": [
{
"id": 4,
"path": "0001",
"depth": 1,
"numchild": 3,
"name": "改色"
},
{
"id": 7,
"path": "00010001",
"depth": 2,
"numchild": 0,
"name": "定制彩绘"
},
{
"id": 6,
"path": "00010002",
"depth": 2,
"numchild": 0,
"name": "渐变色"
}
]
}
小结
还是自己实现的舒服。
不过这个也算是开箱即用了,小项目的话随便搞搞还是可以的。
参考资料
使用django-treebeard实现树类型存储与编辑的更多相关文章
- hibernate —— 树状存储
package com.pt.treeStrut; import java.util.Set; import javax.persistence.CascadeType; import javax.p ...
- django model常用字段类型
摘自 http://www.cnblogs.com/wt869054461/p/4014271.html V=models.AutoField(**options) #int:在Django代码内是自 ...
- php数据结构课程---5、树(树的 存储方式 有哪些)
php数据结构课程---5.树(树的 存储方式 有哪些) 一.总结 一句话总结: 双亲表示法:data parent:$tree[1] = ["B",0]; 孩子表示法:data ...
- 为什么选择b+树作为存储引擎索引结构
为什么选择b+树作为存储引擎索引结构 在数据库或者存储的世界里,存储引擎的角色一直处于核心位置.往简单了说,存储引擎主要负责数据如何读写.往复杂了说,怎么快速.高效的完成数据的读写,一直是存储引擎要解 ...
- 怎样的操作才能让HashMap以红黑树类型存储数据? (文中没有解答该问题)
怎样才能让HashMap以红黑树类型存储数据? 看上面的代码可知:如果一个Node的长度大于等于7.就会触发Node转TreeNode的操作. 我向一个map中插入了一百万条数据(插入一亿条时,内存溢 ...
- 1004 Counting Leaves 对于树的存储方式的回顾
一种新的不使用左右子树递归进行树高计算的方法,使用层次遍历 树的存储方式: 1.本题提供的一种思路: 使用(邻接表的思想)二维数组(vector[n])表示树,横坐标表示 父节点,每一行表示孩子. 能 ...
- C#_02.12_基础二_.NET类型存储和变量
C#_02.12_基础二_.NET类型存储和变量 一.核心一句:C#程序是一组类型声明(留待后面慢慢体会,现在不是很理解,不强说了) 二.数据类型: 1.预定义了16种数据类型: 其中13种简单数据类 ...
- 深入学习C#匿名函数、委托、Lambda表达式、表达式树类型——Expression tree types
匿名函数 匿名函数(Anonymous Function)是表示“内联”方法定义的表达式.匿名函数本身及其内部没有值或者类型,但是可以转换为兼容的委托或者表达式树类型(了解详情).匿名函数转换的计算取 ...
- C#树类型及其遍历
最近有个项目不仅需要取部门的层级关系,还要处理不规则的关系(移除某个部门),只有树结构才能实现相关遍历和操作. 涉及到的知识点:泛型.递归.数据结构 既然研究树类型就先来看下树的定义: 一棵树(tre ...
- mvc 使用预置队列类型存储异常对象
using PaiXie.Utils; using System; using System.Collections.Generic; using System.Linq; using System. ...
随机推荐
- java8 lambda Group分组示例
导入jar包<dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</a ...
- HTML5 在泛在电力物联网的 10 大业务领域 2/3D 可视化应用
过去的 2018 年,我们认为是国内工业互联网可视化的元年,图扑软件作为在工业可视化领域的重度参与者,一线见证了众多 HTML5/Web 化.2D/3D 化的项目在工业界应用落地. 2019 年可以定 ...
- logging.basicConfig()
logging.basicConfig() 是 Python 标准库 logging 模块中的一个函数,用于配置日志记录器(logger)的基本选项.这个函数允许你在不创建和配置多个 logger.h ...
- JavaScript:Function:函数(方法)对象
<!DOCTYPE html><html> <head> <meta charset="utf-8"> ...
- 通俗易懂的路径搜索之A-star算法
A-star算法 搜索技术 搜索技术是一种通用的问题求解技术,可以将待解决的问题转化为可搜索的问题空间,然后在该空间中搜索求解.搜索技术在人工智能领域有着非常广泛的应用. 盲目搜索 盲目搜索是最简单的 ...
- python重拾第十一天-REDIS缓存数据库
缓存数据库介绍 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL",泛指非关系型的数据库,随着互联网web2.0网站的兴起,传统的关系数据库在应付we ...
- 安卓Camera-HAL显示值与比例
安卓Camera-HAL显示值与比例 参考:https://blog.csdn.net/wang714818/article/details/78049649?utm_source=blogxgwz4 ...
- 微服务上云Dockerfile编写,如何上云时将生产环境和开发环境分离并正确书写自定义启动命令
点击查看代码 FROM openjdk:8-jdk LABEL maintainer=yao #docker run -e PARAMS="--server.port 9090" ...
- 不是人家太装逼,而是我们太low
在一个社团的迎新的时候,每个人自我介绍.等到一个一身LV,爱马仕的女孩子自我介绍,说起爱好,她想了想说:喜欢跑车.然后很淡定的坐下了.很多同学你看我我看你,投以"炫富"的判断目光- ...
- Mysql生成实体类
-- 查询数据表结构 SELECT CONCAT('"e.',SUBSTRING(COLUMN_NAME,1),',"+'),COLUMN_NAME,',',COLUMN_TYPE ...