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

如何在Django Admin多对多自动字段中获取选中项实现树形分类搜索

实现Django Admin中Movie分类的树形层级搜索

1. 修改Genre Admin的查询过滤逻辑

在admin.py的AdminGenre类中,重写get_queryset方法,根据请求参数过滤出指定父分类的所有后代节点:

from mptt.admin import DraggableMPTTAdmin
from django.contrib import admin
from .models import Genre, Movie

@admin.register(Genre)
class AdminGenre(DraggableMPTTAdmin):
    list_display = ["tree_actions", "indented_title"]
    list_display_links = ["indented_title"]
    search_fields = ["name__istartswith"]

    def get_queryset(self, request):
        qs = super().get_queryset(request)
        # 获取请求中的父分类ID参数
        parent_id = request.GET.get('parent_id')
        if parent_id:
            try:
                parent_genre = Genre.objects.get(id=parent_id)
                # 获取该父分类的所有后代节点(不包含父分类本身)
                qs = parent_genre.get_descendants(include_self=False)
            except Genre.DoesNotExist:
                qs = qs.none()
        return qs

@admin.register(Movie)
class AdminMovie(admin.ModelAdmin):
    autocomplete_fields = ["genre"]
    
    class Media:
        # 引入自定义JS文件实现前端交互
        js = ('admin/js/genre_autocomplete.js',)

2. 添加前端父分类选择与请求参数传递

在项目的static/admin/js目录下创建genre_autocomplete.js文件,实现父分类选择器并修改自动完成请求的参数:

document.addEventListener('DOMContentLoaded', function() {
    const genreSelect = document.getElementById('id_genre');
    if (!genreSelect) return;

    // 创建父分类选择下拉框
    const parentSelector = document.createElement('select');
    parentSelector.id = 'parent_genre_selector';
    parentSelector.className = 'vTextField';
    parentSelector.style.marginRight = '10px';

    // 添加默认选项
    const defaultOption = document.createElement('option');
    defaultOption.value = '';
    defaultOption.textContent = '选择父分类(可选)';
    parentSelector.appendChild(defaultOption);

    // 加载所有顶级分类(无父分类的节点)
    fetch('/admin/你的应用名/genre/?format=json')  // 替换为你的实际应用名称
        .then(resp => resp.json())
        .then(data => {
            data.forEach(item => {
                if (!item.parent) {
                    const option = document.createElement('option');
                    option.value = item.id;
                    option.textContent = item.name;
                    parentSelector.appendChild(option);
                }
            });
        });

    // 将选择器插入到分类选择框前
    genreSelect.parentNode.insertBefore(parentSelector, genreSelect);

    // 修改Select2的AJAX请求,携带父分类ID参数
    $(genreSelect).on('select2:open', function() {
        const select2 = $(this).data('select2');
        const originalAjax = select2.options.get('ajax');
        
        select2.options.set('ajax', {
            url: originalAjax.url,
            data: function(params) {
                return {
                    term: params.term || '',
                    parent_id: parentSelector.value || ''
                };
            },
            processResults: originalAjax.processResults,
            cache: originalAjax.cache
        });
    });
});

3. 功能效果

  • 在Movie的创建/编辑页面,会新增一个“选择父分类”下拉框,默认展示所有顶级分类。
  • 选择某父分类后,点击Genre的自动完成输入框,搜索结果将仅包含该父分类下的所有子节点(含孙子节点等后代)。
  • 不选择父分类时,搜索逻辑保持原有状态,返回所有分类。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 16:40:22