1、使用Django自带的标签 unordered_list
1.1、定义模型
1 2 3 4 5 6 7 8 9 10 11 12 13
| class Department(models.Model): name = models.CharField(max_length=64, unique=True, verbose_name="部门名称") parent = models.ForeignKey('Department', on_delete=models.PROTECT, null=True, blank=True, db_constraint=False, related_name='children', verbose_name="父级部门")
def __str__(self): return self.name
|
1.2、自定义递归获取函数和view
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| from app.models import Department
def recurse_display(data): """递归展示""" display_list = [] for item in data: display_list.append(item.name) children = item.children.all() if len(children) > 0: display_list.append(recurse_display(children)) return display_list
def depart_tree(request): departs = Department.objects.filter(parent=None) data = recurse_display(departs) return render(request, 'app/tree.html', {'data': data})
|
1.3、页面 template中使用
1 2 3
| The Tree:
{{ data|unordered_list }}
|
1.4、效果如下:
2、使用django-mptt
使用前先安装模块
然后需要在 INSTALLED_APPS 中配置上
1 2 3 4
| INSTALLED_APPS = [ ... ... 'mptt', ]
|
2.1、定义模型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| from mptt.models import MPTTModel
class DepartMPTT(MPTTModel): name = models.CharField(max_length=64, unique=True, verbose_name="部门名称") parent = models.ForeignKey('DepartMPTT', on_delete=models.PROTECT, null=True, blank=True, db_constraint=False, related_name='children', verbose_name="父级部门")
def __str__(self): return self.name
|
注意在model中的 MPTTMeta如果父字段使用的不是parent
名称,就需要单独在 MPTTMeta
中说明
2.2、定义view
1 2 3 4 5
| from app.models import DepartMPTT
def depart_mptt_tree(request): departs = DepartMPTT.objects.all() return render(request, 'app/mptt.html', {'departs': departs})
|
这里网上有些文章说必须在context中使用nodes
才可以,即 {'nodes': departs}
;其实进过验证不必非得是nodes才行,比如这里的 departs
2.3、在template中使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| {% load mptt_tags %}
{% recursetree departs %} <li> {% if node.is_leaf_node %} <span style="color: orange;">{{ node.name }}</span> {% else %} <span style="color: red;">{{ node.name }}</span> <ul> {{ children }} </ul> {% endif %} </li> {% endrecursetree %}
|
这里需要注意的是,在前端代码中node有时候有特殊含义,可以使用 with 标签进行替换,注意标记要闭合结束 {% endwith %}
2.4、扩展admin
mptt提供了对应的admin类,在后台添加和展示 MTPPModel 的时候会更友好些
1 2 3 4
| from .models import DepartMPTT from mptt.admin import MPTTModelAdmin
admin.site.register(DepartMPTT, MPTTModelAdmin)
|
具体效果就不给大家展示,可以自己尝试下
最终效果和上面第一种方式的效果类似。
3、项目代码
具体的源码和使用说明详见 https://gitee.com/colin5063/django_learning/tree/django_tree/
感兴趣的可以扫码关注个人微信公众号,文章首发