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

在Django中实现子部门基于主部门的联动选择

在Django中实现子部门基于主部门的联动选择

嘿,我明白你的问题了——你希望实现部门和子部门的联动下拉:选完主部门后,子部门的下拉列表只显示属于这个主部门的选项,而不是把所有子部门都列出来对吧?这在Django里需要结合后端API和前端JS来实现,我一步步给你说怎么做:

第一步:完善模型小细节

我看到你的SubDepartment模型的__str__方法没写完,先补上这行,方便在后台和下拉框里正常显示子部门名称:

class SubDepartment(models.Model):
    sub_department_name=models.CharField(max_length=100,null=False,blank=False)
    department_name=models.ForeignKey(Department,on_delete=models.CASCADE)
    company_name=models.ForeignKey(CompanyName,on_delete=models.CASCADE)
    status=models.CharField(max_length=20, choices=[('active','Active'),('inactive','Inactive')])

    def __str__(self):
        return self.sub_department_name  # 补上这行

另外,子部门的company_name其实可以通过关联的主部门自动获取,不用手动选择,这样能避免用户选错。这个逻辑我们可以在表单里处理,后面会提到。

第二步:添加后端API接口,根据部门ID获取子部门

我们需要写一个视图,接收前端传来的部门ID,返回对应的子部门列表,供前端动态调用。在views.py里添加:

from django.http import JsonResponse

def get_sub_departments(request):
    # 获取前端传过来的部门ID
    department_id = request.GET.get('department_id')
    if department_id:
        # 过滤出属于该部门的子部门,只返回ID和名称字段
        sub_depts = SubDepartment.objects.filter(department_name_id=department_id).values('id', 'sub_department_name')
        return JsonResponse(list(sub_depts), safe=False)
    # 如果没有传部门ID,返回空列表
    return JsonResponse([], safe=False)

然后在你的urls.py里添加这个路由:

path('get-sub-depts/', views.get_sub_departments, name='get-sub-depts'),

第三步:优化子部门表单(可选)

如果是添加子部门的表单,其实不需要让用户手动选company_name,因为子部门的公司肯定和主部门的公司一致。你可以修改SubDepartmentForm,自动填充这个字段:

class SubDepartmentForm(forms.ModelForm):
    class Meta:
        model = SubDepartment
        # 去掉company_name,不让用户手动选择
        fields = ['sub_department_name', 'department_name', 'status']

    def save(self, commit=True):
        instance = super().save(commit=False)
        # 从选中的主部门获取公司名称,自动赋值
        instance.company_name = instance.department_name.company_name
        if commit:
            instance.save()
        return instance

第四步:前端实现联动逻辑

假设你是在需要同时选择部门和子部门的页面(比如员工信息表单、关联表单),需要在模板里添加JS来监听部门下拉的变化,动态更新子部门选项。下面是示例代码:

<!-- 你的表单部分 -->
<form method="POST">
    {% csrf_token %}
    <div class="form-group">
        <label for="id_department_name">选择主部门</label>
        {{ form.department_name }}  <!-- 这是部门的下拉框 -->
    </div>
    <div class="form-group">
        <label for="id_sub_department_name">选择子部门</label>
        {{ form.sub_department_name }}  <!-- 这是子部门的下拉框 -->
    </div>
    <!-- 其他表单字段 -->
    <button type="submit">提交</button>
</form>

<!-- 引入jQuery(如果你的项目已经有JS库,就用你自己的) -->
<script src="https://code.jquery.com/jquery-3.6.4.min.js"></script>
<script>
$(document).ready(function() {
    // 监听主部门下拉框的变化事件
    $('#id_department_name').change(function() {
        const departmentId = $(this).val();
        
        // 发送AJAX请求到我们刚才写的API
        $.ajax({
            url: "{% url 'get-sub-depts' %}",
            data: { 'department_id': departmentId },
            dataType: 'json',
            success: function(subDepts) {
                // 清空子部门下拉框
                $('#id_sub_department_name').empty();
                // 添加默认提示选项
                $('#id_sub_department_name').append('<option value="">请选择子部门</option>');
                // 遍历返回的子部门,添加到下拉框里
                $.each(subDepts, function(index, dept) {
                    $('#id_sub_department_name').append(`<option value="${dept.id}">${dept.sub_department_name}</option>`);
                });
            }
        });
    });

    // 如果页面加载时已经选中了主部门(比如编辑页面),自动触发一次变化事件,加载对应的子部门
    const initialDeptId = $('#id_department_name').val();
    if (initialDeptId) {
        $('#id_department_name').trigger('change');
    }
});
</script>

为什么你的现有代码没生效?

你现在的表单只是普通的ModelForm,默认的下拉框是后端渲染的静态内容,页面加载后就固定了。要实现动态过滤,必须用前端JS配合后端API来实时获取对应的数据,这样才能做到选完主部门后,子部门列表自动更新。

这样改完之后,当你选完主部门,子部门下拉就只会显示属于这个主部门的选项啦!

备注:内容来源于stack exchange,提问作者Anwar Ahammed

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.13 20:18:00