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

Django Admin实现产品分类关联子分类动态过滤

Django Admin实现Product分类与子分类联动

要实现选择Category后,Sub_Category下拉框仅展示对应子分类的效果,需要结合后端接口和前端JS联动来完成,具体步骤如下:

步骤1:创建获取子分类的后端视图

在你的app下的views.py中添加一个视图,用于根据分类ID返回对应的子分类数据:

from django.http import JsonResponse
from .models import Sub_Category

def get_subcategories(request):
    category_id = request.GET.get('category_id')
    subcategories = Sub_Category.objects.filter(category_id=category_id).values('id', 'sub_category_name')
    return JsonResponse(list(subcategories), safe=False)

接着在项目或app的urls.py中添加该视图的路由:

from django.urls import path
from . import views

urlpatterns = [
    # 其他已有路由...
    path('get-subcategories/', views.get_subcategories, name='get_subcategories'),
]

步骤2:自定义Product的Admin类

在admin.py中自定义Product的Admin管理类,并关联前端JS资源:

from django.contrib import admin
from .models import Product, Category, Sub_Category

class ProductAdmin(admin.ModelAdmin):
    list_display = ('product_name', 'category', 'sub_category', 'price')
    
    # 绑定前端JS文件
    class Media:
        js = ('js/category_subcategory联动.js',)  # 路径对应static文件夹下的js目录

admin.site.register(Product, ProductAdmin)
admin.site.register(Category)
admin.site.register(Sub_Category)

步骤3:编写前端联动JavaScript

在项目的static/js目录下创建category_subcategory联动.js文件,编写以下联动逻辑:

document.addEventListener('DOMContentLoaded', function() {
    const categorySelect = document.querySelector('#id_category');
    const subcategorySelect = document.querySelector('#id_sub_category');
    const originalOptions = Array.from(subcategorySelect.options);
    
    // 监听分类选择变化
    categorySelect.addEventListener('change', function() {
        const categoryId = this.value;
        
        if (!categoryId) {
            // 未选分类时重置子分类选项
            subcategorySelect.innerHTML = '';
            originalOptions.forEach(option => subcategorySelect.appendChild(option));
            return;
        }
        
        // 异步请求对应子分类
        fetch(`/get-subcategories/?category_id=${categoryId}`)
            .then(res => res.json())
            .then(data => {
                subcategorySelect.innerHTML = '<option value="">----------</option>';
                data.forEach(item => {
                    const option = document.createElement('option');
                    option.value = item.id;
                    option.textContent = item.sub_category_name;
                    subcategorySelect.appendChild(option);
                });
                
                // 编辑页面时自动选中原有子分类
                const currentSubId = subcategorySelect.dataset.current;
                if (currentSubId) subcategorySelect.value = currentSubId;
            })
            .catch(err => console.error('加载子分类失败:', err));
    });
    
    // 页面加载时,若已有分类则触发一次加载
    if (categorySelect.value) {
        categorySelect.dispatchEvent(new Event('change'));
    }
    
    // 保存编辑页面的原有子分类ID
    if (subcategorySelect.value) {
        subcategorySelect.dataset.current = subcategorySelect.value;
    }
});

注意事项

  • 确保项目已正确配置静态文件(STATIC_URL、STATIC_ROOT),且static/js目录存在
  • 若自定义了Admin模板,需确认JS中的选择器#id_category、#id_sub_category与实际DOM元素ID匹配
  • 可给后端视图添加@login_required装饰器,限制仅后台用户能访问接口

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 13:45:39