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

如何在Django Admin中基于分类下拉框过滤类型下拉选项?

实现Django Admin中Category与ItemType的联动下拉过滤

先修复模型定义问题

Plant模型的name字段缺少必填参数,先补充完整:

class Plant(models.Model):
    category = models.ForeignKey(Category , on_delete=models.SET_NULL , null=True)
    type = models.ForeignKey(ItemType, on_delete=models.SET_NULL,null = True)
    name = models.CharField(max_length=200)  # 添加max_length参数

步骤1:编写获取ItemType的后端视图

在你的app目录下的views.py中添加以下视图,用于根据分类ID返回对应的类型数据:

from django.http import JsonResponse
from .models import ItemType

def get_item_types(request):
    category_id = request.GET.get('category_id')
    # 过滤出指定分类下的ItemType,只返回id和name字段
    item_types = ItemType.objects.filter(category_id=category_id).values('id', 'name')
    return JsonResponse(list(item_types), safe=False)

步骤2:配置路由

在app目录下的urls.py中添加视图路由:

from django.urls import path
from . import views

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

确保项目根目录的urls.py已经包含该app的路由(比如path('your-app-name/', include('your_app.urls')))。

步骤3:自定义Admin表单与媒体资源

在app目录下的admin.py中,自定义Plant的管理表单,并引入JS实现联动:

from django import forms
from django.contrib import admin
from .models import Category, ItemType, Plant

# 自定义Plant管理表单
class PlantAdminForm(forms.ModelForm):
    class Meta:
        model = Plant
        fields = '__all__'

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        # 初始化时,如果已有选中的分类,过滤对应的类型选项
        if self.instance.category:
            self.fields['type'].queryset = ItemType.objects.filter(category=self.instance.category)
        else:
            self.fields['type'].queryset = ItemType.objects.none()

# 配置Plant的Admin类
class PlantAdmin(admin.ModelAdmin):
    form = PlantAdminForm

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

# 注册模型
admin.site.register(Category)
admin.site.register(ItemType)
admin.site.register(Plant, PlantAdmin)

步骤4:编写JS联动逻辑

在项目的static/admin/js/目录下创建plant_admin.js文件(若目录不存在则手动创建),写入以下代码:

document.addEventListener('DOMContentLoaded', function() {
    const categorySelect = document.getElementById('id_category');
    const typeSelect = document.getElementById('id_type');

    // 监听分类下拉框的变化事件
    categorySelect.addEventListener('change', function() {
        const categoryId = this.value;
        // 清空类型下拉框
        typeSelect.innerHTML = '<option value="">---------</option>';

        if (categoryId) {
            // 发送请求获取对应分类的类型数据
            fetch(`/your-app-name/get-item-types/?category_id=${categoryId}`)
                .then(response => response.json())
                .then(data => {
                    data.forEach(itemType => {
                        const option = document.createElement('option');
                        option.value = itemType.id;
                        option.textContent = itemType.name;
                        typeSelect.appendChild(option);
                    });
                })
                .catch(error => console.error('加载类型数据失败:', error));
        }
    });
});

注意将/your-app-name/替换为你实际的app路由前缀(比如app名为plants则写/plants/)。


额外注意事项

  • 确保项目settings.py中已正确配置STATIC_URL和STATICFILES_DIRS,静态文件能被正常加载;
  • 生产环境下需要执行python manage.py collectstatic收集静态文件;
  • 测试时若JS未生效,可尝试清除浏览器缓存。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.21 05:15:33