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

Django Admin中如何根据选中的Department动态过滤Student关联的Branch选项

Django Admin 实现部门-分支联动下拉方案

两种实现方案可按需选择:

方案1:原生实时联动(无需第三方依赖,交互体验好)

第一步:自定义Student表单过滤初始分支选项

在admin.py中新增表单逻辑:

import uuid
from django import forms
from django.contrib import admin
from django.http import JsonResponse
from django.urls import path
from .models import Department, Branch, Student

class StudentForm(forms.ModelForm):
    class Meta:
        model = Student
        fields = "__all__"
    
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 编辑已有学生时,仅加载对应部门的分支
        if self.instance.pk and self.instance.department:
            self.fields['branch'].queryset = Branch.objects.filter(dep=self.instance.department)
        # 新增学生时默认分支选项为空
        else:
            self.fields['branch'].queryset = Branch.objects.none()

第二步:新增联动JS脚本

在项目static目录下新建admin/student_form.js,内容如下:

django.jQuery(document).ready(function($) {
    const deptSelect = $('#id_department');
    const branchSelect = $('#id_branch');

    function loadRelatedBranches() {
        const deptId = deptSelect.val();
        branchSelect.empty();
        if (!deptId) return;
        // 请求对应部门的分支列表
        $.get(`/admin/student/get-branches/?dept_id=${deptId}`, function(data) {
            data.forEach(item => {
                branchSelect.append(new Option(item.name, item.id));
            });
        });
    }
    // 页面加载时如果已有选中部门自动加载分支
    if (deptSelect.val()) loadRelatedBranches();
    // 部门变更时刷新分支选项
    deptSelect.on('change', loadRelatedBranches);
});

注意需要确保你的Django项目配置了正确的静态文件访问规则,自定义JS文件放在对应static目录下才能正常加载

第三步:注册StudentAdmin并添加分支查询接口

继续在admin.py中添加如下代码:

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    form = StudentForm
    # 注入自定义联动JS
    class Media:
        js = ('admin/student_form.js',)
    
    # 注册分支查询接口
    def get_urls(self):
        urls = super().get_urls()
        custom_urls = [
            path('get-branches/', self.admin_site.admin_view(self.get_branch_list), name='student-get-branches'),
        ]
        return custom_urls + urls
    
    def get_branch_list(self, request):
        dept_id = request.GET.get('dept_id')
        if not dept_id:
            return JsonResponse([], safe=False)
        branches = Branch.objects.filter(dep_id=dept_id).values('id', 'name')
        return JsonResponse(list(branches), safe=False)

# 其他模型注册保持原有逻辑即可
admin.site.register(Department)
admin.site.register(Branch)

方案2:轻量实现(无JS,仅编辑时过滤)

如果不需要实时联动,只需要编辑已有学生时显示对应分支,可直接重写formfield_for_foreignkey方法,代码更简单:

@admin.register(Student)
class StudentAdmin(admin.ModelAdmin):
    def formfield_for_foreignkey(self, db_field, request, **kwargs):
        if db_field.name == 'branch':
            object_id = request.resolver_match.kwargs.get('object_id')
            if object_id:
                student = Student.objects.get(pk=object_id)
                kwargs['queryset'] = Branch.objects.filter(dep=student.department)
            else:
                kwargs['queryset'] = Branch.objects.none()
        return super().formfield_for_foreignkey(db_field, request, **kwargs)

该方案缺点是新增学生时选完部门需要先保存一次,再次编辑时才会显示对应分支选项,适合对交互要求不高的场景。

内容的提问来源于stack exchange,提问作者Ali

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 10:15:09