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

如何在Django模型中创建分类与子分类?实现汽车品牌系列级联选择

Django Admin实现品牌与系列联动筛选

针对你在汽车交易市场网站中遇到的问题——在管理后台创建Car时,选择品牌后仅显示对应系列,可通过以下步骤实现:

1. 自定义Car模型表单

在admin.py中创建自定义表单,初始化时根据当前实例设置系列的可选范围:

from django.contrib import admin
from django import forms
from django.urls import reverse, path
from django.http import JsonResponse
from .models import Brand, Series, Car

class CarForm(forms.ModelForm):
    class Meta:
        model = Car
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 编辑页面时,默认显示当前车辆品牌对应的系列
        if self.instance.pk:
            self.fields['series'].queryset = Series.objects.filter(brand=self.instance.brand)
        # 新增页面时默认隐藏所有系列,待选择品牌后加载
        else:
            self.fields['series'].queryset = Series.objects.none()

2. 扩展CarAdmin类并添加联动接口

在admin.py中自定义Car的Admin类,添加动态获取系列的视图,并引入前端JS:

class CarAdmin(admin.ModelAdmin):
    form = CarForm

    # 引入自定义JS文件
    class Media:
        js = ('admin/js/car_series_filter.js',)

    # 提供根据品牌ID获取系列的接口
    def get_series_by_brand(self, request):
        brand_id = request.GET.get('brand_id')
        series_list = Series.objects.filter(brand_id=brand_id).values('id', 'series')
        return JsonResponse(list(series_list), safe=False)

    # 注册自定义接口URL
    def get_urls(self):
        base_urls = super().get_urls()
        custom_urls = [
            path('get-series-by-brand/', self.get_series_by_brand, name='get-series-by-brand'),
        ]
        return custom_urls + base_urls

# 注册模型到admin
admin.site.register(Brand)
admin.site.register(Series)
admin.site.register(Car, CarAdmin)

3. 编写前端联动JS

在项目的static/admin/js/目录下创建car_series_filter.js文件,实现品牌选择后的系列动态加载:

document.addEventListener('DOMContentLoaded', function() {
    const brandSelect = document.getElementById('id_brand');
    const seriesSelect = document.getElementById('id_series');

    // 品牌选择变化时触发系列更新
    brandSelect.addEventListener('change', function() {
        const brandId = this.value;
        seriesSelect.innerHTML = '<option value="">---------</option>';
        
        if (brandId) {
            // 替换yourappname为你的实际应用名称
            fetch(`/admin/yourappname/car/get-series-by-brand/?brand_id=${brandId}`)
                .then(res => res.json())
                .then(data => {
                    data.forEach(item => {
                        const option = document.createElement('option');
                        option.value = item.id;
                        option.textContent = item.series;
                        seriesSelect.appendChild(option);
                    });
                });
        }
    });

    // 编辑页面初始化时自动加载对应系列
    if (brandSelect.value && seriesSelect.options.length === 1) {
        brandSelect.dispatchEvent(new Event('change'));
    }
});

可选优化建议

你的Car模型中同时存储了brand和series字段,而Series已经通过外键关联了Brand,实际上可以移除Car中的brand字段,通过car.series.brand即可获取对应品牌,避免数据冗余。如果需要保留当前结构,以上方案完全适用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 14:57:39