Implementing Tree-Type Storage and Editing with django-treebeard
Simply inherit the MP_Node configuration for TreeAdmin, enabling drag-and-drop editing of tree nodes. For visualization? Only django-treebeard is usable; others are either discontinued or have subpar functionality. For initializing data? Manual import is required; otherwise, the admin interface doesn’t even have a button—buggy. The API output is just path and depth—it’s more comfortable to implement this yourself.
目录9 个章节
Preface
Actually,in many previous projects,I encountered features related to trees. In the past,I always implemented them myself. Later on,many frontend UI component libraries included Tree components,which you could just plug in and use.
However,since we’re using Django,it’s important to make full use of its ecosystem. But after searching for a long time,the only usable option I found was this treebeard. The others have either been discontinued or have very limited functionality—they lack visual tree-editing capabilities.
Could it be that Django has already declined?
Effect
Take this car modification project as an example.
Achieve the following effect, which allows dragging nodes for editing.

Installation
Install dependencies
pdm add django-treebeard
Add treebeard to INSTALLED_APPS
Defining a Model
Just inherit from the MP_Node type.
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
Configure admin
To implement visual tree editing, you need to inherit from TreeAdmin.
from treebeard.admin import TreeAdmin
@admin.register(CaseCategory)
class CaseCategoryAdmin(TreeAdmin):
form = movenodeform_factory(CaseCategory)
list_display = ['name', 'depth']
search_fields = ['name']
Initializing Data
You can use code to import the initial Tree data.
(In fact, it's because if you don't import the initialization data first, the admin interface won't even show an add button... I guess it's a 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='省心提')
This way, once you open the admin interface, you'll be able to see the data.
Good enough, I guess.
Write an API Endpoint
Then I'll write a simple API endpoint based on django-ninja
(Actually, this code is auto-generated by 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
The resulting data looks like this (some data omitted)
{
"code": 200,
"data": [
{
"id": 4,
"path": "0001",
"depth": 1,
"numchild": 3,
"name": "Color Change"
},
{
"id": 7,
"path": "00010001",
"depth": 2,
"numchild": 0,
"name": "Custom Airbrush Painting"
},
{
"id": 6,
"path": "00010002",
"depth": 2,
"numchild": 0,
"name": "Gradient Color"
}
]
}
Summary
Still more comfortable with a self-implemented solution.
But this one is pretty much out of the box too—it's fine for tinkering around in small projects.
References
_EOF_
Implementing Tree-Type Storage and Editing with django-treebeard
- 本文作者:
- 程序设计实验室
- 版权声明:
- 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
相关文章
Django项目笔记:sessions处理以及复杂对象序列化
前言:一点题外话 我发现,不更新博客的时候,不是非常忙,就是效率非常低。最近没怎么更新博客,原因是第二种= =。惭愧惭愧。 今天效率出奇的高,一天时间把PassNote后端的接口全部写完了,Django很好用,不过实际项目中还是有些框架不能实现的功能需要解决的,我比较喜欢造轮子,不过为了保证效率,还是尽量用现成的工具,减少不必要的折腾。 关于PassNote 之前应该在博客有说过,这是一个密码管理
2022-04-02 · Django · 约 1 分钟
Django中间件之实现Admin后台IP白名单
前言 Django自带的Admin管理后台很方便,但是实际生产环境真的会有挺多安全问题的,在admin的安全防护这方面,我之前就研究实现了给admin加上登录验证码和限流功能,可以参考这篇文章:给Django Admin添加验证码和多次登录尝试限制 不过就在内部使用的话就好很多,因此我们可以通过Django的中间件来实现IP过滤,所以本文中涉及到两个知识点,一个是Django的中间件,另外一个是P
2022-08-26 · Django · 约 1 分钟
给Django的Admin添加自定义Action-并移除需要选择对象的限制
前言 不得不说,Django的Admin真的给开发带来很多便利,这不,我又来折腾了,这次是添加自定义的action 这个自定义的Action可以看看官方文档的介绍,很详细,不再赘述。 https://docs.djangoproject.com/en/3.0/ref/contrib/admin/actions/ 界面效果 Django默认的添加完action是要选择下面的对象才能提交的,不过我不需
2022-08-26 · Django · 约 1 分钟
不同Django服务器和部署方式的性能调研
WSGI 排名靠前?uWSGI 才是王道。ASGI 增加复杂度,性能还差一截。腾讯云服务器性能还掉线?真是够了。
2025-11-28 · Django · 约 1 分钟
讨论
共 0 条加载评论中…