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

如何在Django Admin中实现商品主分类与子分类的联动选择功能

解决Django Admin中主分类与子分类的联动问题

我来帮你搞定这个需求——在Django Admin里选完商品的主分类后,子分类下拉框只显示对应主分类的选项,而不是全部子分类。咱们用原生AJAX + Django视图的方式实现,不需要额外安装第三方库,具体步骤如下:

1. 新增获取子分类的视图

首先,在你的app的views.py里添加一个视图,用来根据主分类ID返回对应的子分类数据:

from django.http import JsonResponse
from .models import SubCategory

def get_subcategories(request):
    # 获取传入的主分类ID
    category_id = request.GET.get('category_id')
    # 过滤出对应主分类的子分类,只取id和title字段
    subcategories = SubCategory.objects.filter(main_category_id=category_id).values('id', 'title')
    # 返回JSON格式的数据
    return JsonResponse(list(subcategories), safe=False)

2. 配置视图路由

在项目的urls.py(或者app的urls.py)里添加这个视图的路由:

from django.urls import path
from . import views

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

3. 编写Admin页面的联动JS代码

在你的app下创建static/admin/js/目录(如果没有的话),新建product_admin.js文件,写入以下代码:

document.addEventListener('DOMContentLoaded', function() {
    // 获取主分类和子分类的下拉框元素
    const mainCategorySelect = document.getElementById('id_maincategory');
    const subCategorySelect = document.getElementById('id_subcategory');

    // 监听主分类选择变化的事件
    mainCategorySelect.addEventListener('change', function() {
        const categoryId = this.value;
        
        // 先清空子分类下拉框
        subCategorySelect.innerHTML = '<option value="">---------</option>';
        
        // 如果主分类没选,直接返回
        if (!categoryId) return;

        // 发送AJAX请求获取子分类
        fetch(`/get-subcategories/?category_id=${categoryId}`, {
            headers: {
                // 带上CSRF令牌,避免403错误
                'X-CSRFToken': getCookie('csrftoken')
            }
        })
        .then(response => response.json())
        .then(data => {
            // 把返回的子分类填充到下拉框里
            data.forEach(subcat => {
                const option = document.createElement('option');
                option.value = subcat.id;
                option.textContent = subcat.title;
                subCategorySelect.appendChild(option);
            });
        })
        .catch(err => console.error('加载子分类出错:', err));
    });

    // 页面加载完成时,如果已有主分类值,自动触发加载子分类
    if (mainCategorySelect.value) {
        mainCategorySelect.dispatchEvent(new Event('change'));
    }
});

// 辅助函数:获取CSRF令牌
function getCookie(name) {
    let cookieValue = null;
    if (document.cookie && document.cookie !== '') {
        const cookies = document.cookie.split(';');
        for (let i = 0; i < cookies.length; i++) {
            const cookie = cookies[i].trim();
            if (cookie.substring(0, name.length + 1) === (name + '=')) {
                cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
                break;
            }
        }
    }
    return cookieValue;
}

4. 修改Product的Admin类,引入JS文件

在你的app的admin.py里,修改ProductAdmin类,添加Media属性来引入刚才写的JS文件:

from django.contrib import admin
from .models import Product

class ProductAdmin(admin.ModelAdmin):
    # 这里可以保留你原来的配置,比如list_display、fields等
    # 新增Media属性,引入自定义JS
    class Media:
        js = ('admin/js/product_admin.js',)

# 注册Product模型和对应的Admin类
admin.site.register(Product, ProductAdmin)

注意事项

  • 确保你的Django项目已经正确配置了静态文件:INSTALLED_APPS里包含django.contrib.staticfiles,STATIC_URL设置为'/static/'
  • 如果是编辑已有的商品,页面加载时会自动根据已选的主分类加载对应的子分类
  • 测试时如果遇到403错误,检查CSRF令牌是否正确获取,或者确认视图的URL路径是否正确

这样配置完成后,你在Django Admin里添加或编辑商品时,选择主分类后,子分类下拉框就只会显示该主分类下的子分类啦!

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 20:07:46