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
相关产品推荐
相关产品推荐

