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

Django关联三个模型实现Rubric变动时Sub_Rubric列表联动的方法

Django联动下拉功能实现方案

你现有的模型关联逻辑已经符合要求,二级分类联动属于表单交互层逻辑,不需要修改模型关联关系,按以下步骤实现即可:


一、先修正现有模型的小问题

你当前Bb模型中rubric字段的related_name设置有误:related_name是反向关联调用时的别名,和Rubric模型的name字段冲突,建议修改:

# 原代码
rubric = models.ForeignKey(Rubric, null=True, on_delete = models.PROTECT, related_name='name')
# 修改后
rubric = models.ForeignKey(Rubric, null=True, on_delete = models.PROTECT, related_name='bbs')

二、核心联动逻辑实现

分两种常用场景说明:

场景1:Django Admin后台实现联动

1. 自定义表单类初始化子分类筛选规则

from django import forms
from .models import Bb, Sub_Rubric

class BbAdminForm(forms.ModelForm):
    class Meta:
        model = Bb
        fields = "__all__"

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 编辑状态下已选一级分类时,仅显示对应二级分类
        if self.instance.pk and self.instance.rubric:
            self.fields["sub_rubric"].queryset = Sub_Rubric.objects.filter(
                rubric=self.instance.rubric
            )
        # 新增状态下默认无一级分类,二级分类置空
        else:
            self.fields["sub_rubric"].queryset = Sub_Rubric.objects.none()

2. Admin配置注入JS实现前端动态刷新

from django.contrib import admin

class BbAdmin(admin.ModelAdmin):
    form = BbAdminForm
    # 引入自定义JS处理下拉变更事件
    class Media:
        js = ("js/bb_rubric_linkage.js",)

admin.site.register(Bb, BbAdmin)

对应的bb_rubric_linkage.js代码(放在你项目的静态文件目录下):

django.jQuery(document).ready(function ($) {
    const rubricSel = $("#id_rubric");
    const subRubricSel = $("#id_sub_rubric");

    function refreshSubRubric() {
        const rubricId = rubricSel.val();
        subRubricSel.empty();
        if (!rubricId) return;
        // 请求后端接口获取对应一级分类下的二级分类
        fetch(`/api/get_sub_rubric/?rid=${rubricId}`)
            .then((res) => res.json())
            .then((list) => {
                list.forEach((item) => {
                    subRubricSel.append(new Option(item.name, item.id));
                });
            });
    }

    // 监听一级分类变更事件
    rubricSel.on("change", refreshSubRubric);
    // 页面加载时初始化二级分类选项
    refreshSubRubric();
});

3. 新增接口返回二级分类数据

在项目urls.py中新增路由:

from django.http import JsonResponse
from .models import Sub_Rubric

def get_sub_rubric(request):
    rid = request.GET.get("rid")
    subs = Sub_Rubric.objects.filter(rubric_id=rid).values("id", "name")
    return JsonResponse(list(subs), safe=False)

urlpatterns = [
    # 原有路由不变
    path("api/get_sub_rubric/", get_sub_rubric),
]

场景2:自定义前端页面实现联动

逻辑和Admin场景完全一致:

  • 页面初始化时仅加载一级分类选项,二级分类下拉框置空
  • 监听一级分类下拉的change事件,拿到选中的一级分类ID请求后端接口
  • 将接口返回的二级分类数据填充到二级下拉框即可

三、数据一致性校验

为了避免恶意提交不符合关联关系的分类组合,可在Bb模型中添加clean校验:

from django.core.exceptions import ValidationError

class Bb(models.Model):
    # 原有字段不变
    def clean(self):
        if self.rubric and self.sub_rubric:
            if self.sub_rubric.rubric != self.rubric:
                raise ValidationError("所选子分类不属于当前一级分类")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 21:36:03