前言
其实之前做很多项目都有遇到跟树相关的功能,以前都是自己实现的,然后前端很多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": "渐变色"
}
]
}
小结
还是自己实现的舒服。
不过这个也算是开箱即用了,小项目的话随便搞搞还是可以的。