You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python和Django实现员工层级树状结构网页展示?

员工层级树状结构实现方案

问题背景

需要用Python和Django实现员工层级树状展示,预期结构如下:

Employee-1 (Manager -)
    Employee-2 (Manager:Employee-1)
        Employee-3 (Manager :Employee-2)
            Employee-4 (Manager:Employee-3)
    Employee-5 (Manager :Employee-1)
        Employee-6 (Manager:Employee-5)
            Employee-7 (Manager :Employee-6)
        Employee-8 (Manager:Employee-5)

现有models.py代码:

class Employee(models.Model):
    name = models.CharField(max_length=100)
    position = models.CharField(max_length=100)
    hire_date = models.DateField()
    salary = models.DecimalField(max_digits=8, decimal_places=2)
    manager = models.ForeignKey('self', on_delete=models.CASCADE, related_name='subordinates')

尝试的代码出现重复展示问题:每个员工既作为独立项渲染,又作为下属再次渲染,导致层级混乱。


解决方案

1. 模型调整

首先修正manager字段,允许顶级员工(无上级)存在,设置为可空:

class Employee(models.Model):
    name = models.CharField(max_length=100)
    position = models.CharField(max_length=100)
    hire_date = models.DateField()
    salary = models.DecimalField(max_digits=8, decimal_places=2)
    # 允许manager为空,支持顶级员工
    manager = models.ForeignKey(
        'self',
        on_delete=models.CASCADE,
        related_name='subordinates',
        null=True,
        blank=True
    )

2. 视图优化

只查询没有上级的顶级员工,并通过prefetch_related预加载下属,减少数据库查询次数:

# views.py
def employee_hierarchy(request):
    # 过滤出所有顶级员工(无manager的),并预加载下属
    top_employees = Employee.objects.filter(manager__isnull=True).prefetch_related('subordinates')
    return render(request, 'employees/employee_hierarchy.html', {'top_employees': top_employees})

3. 模板修改

主模板 employee_hierarchy.html

只循环渲染顶级员工,避免重复:

<body>
   <h1>Employee Hierarchy</h1>
   <ul>
       {% for employee in top_employees %}
           {% include 'employees/employee_item.html' with employee=employee %}
       {% endfor %}
   </ul>
</body>

递归子模板 employee_item.html

保持递归渲染下属,优化经理显示逻辑,用缩进区分层级:

<li>{{ employee.name }} ({{ employee.position }}) - {% if employee.manager %}Manager: {{ employee.manager.name }}{% else %}Manager -{% endif %}</li>
{% if employee.subordinates.all %}
   <!-- 用缩进区分层级 -->
   <ul style="margin-left: 25px;">
       {% for subordinate in employee.subordinates.all %}
           {% include 'employees/employee_item.html' with employee=subordinate %}
       {% endfor %}
   </ul>
{% endif %}

逻辑实现的最佳位置

  • 模型层:负责定义数据结构(如设置可空的manager字段、关联名称),可添加简单的辅助方法,但不要放置复杂业务逻辑。
  • 视图层:负责数据查询、过滤和预处理(如筛选顶级员工、预加载关联数据),这部分逻辑放在视图更合适,避免模板承担数据处理职责。
  • 模板层:仅专注于渲染界面,用递归include实现层级展示,保持模板简洁,只做数据展示工作。

内容的提问来源于stack exchange,提问作者Кирилл Миронов

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 09:07:43