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

