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

Django应用中如何用JS实现按选中分类筛选机构

实现分类筛选机构的方案

1. 后端准备关联映射数据

先在视图层生成分类ID与对应机构的映射关系,转成JSON格式传递给前端,避免前端频繁遍历所有机构,提升筛选效率:

# views.py
from django.shortcuts import render
import json
from .models import Category, Institution

def step_form(request):
    categories = Category.objects.all()
    institutions = Institution.objects.all()
    
    # 构建分类ID到机构的映射字典
    category_inst_map = {}
    for inst in institutions:
        # 假设Institution与Category是多对多关系,字段名为categories
        for cat in inst.categories.all():
            cat_id_str = str(cat.id)
            if cat_id_str not in category_inst_map:
                category_inst_map[cat_id_str] = []
            category_inst_map[cat_id_str].append({
                'id': str(inst.id),
                'name': inst.name
                # 按需添加其他机构字段
            })
    
    # 转义后传递给模板
    cat_inst_json = json.dumps(category_inst_map)
    return render(request, 'step_form.html', {
        'categories': categories,
        'institutions': institutions,
        'cat_inst_json': cat_inst_json
    })

2. 前端模板与交互逻辑

在分步表单中,给分类选择框绑定事件,根据选中的分类ID筛选并展示对应机构:

<!-- step_form.html -->
<!-- 步骤1:分类选择区域 -->
<div id="step1" class="form-step">
    <h3>选择分类</h3>
    {% for category in categories %}
        <label class="category-label">
            <input type="checkbox" class="category-checkbox" value="{{ category.id }}">
            {{ category.name }}
        </label>
    {% endfor %}
</div>

<!-- 步骤3:机构展示区域 -->
<div id="step3" class="form-step">
    <h3>选择机构</h3>
    <div id="institution-list">
        <!-- 初始渲染所有机构并隐藏 -->
        {% for inst in institutions %}
            <div class="institution-item" data-inst-id="{{ inst.id }}" style="display: none;">
                <label>
                    <input type="checkbox" name="selected_institutions" value="{{ inst.id }}">
                    {{ inst.name }}
                </label>
            </div>
        {% endfor %}
    </div>
</div>

<script>
// 解析后端传递的分类-机构映射
const categoryInstMap = JSON.parse('{{ cat_inst_json|escapejs }}');
const categoryCheckboxes = document.querySelectorAll('.category-checkbox');
const institutionItems = document.querySelectorAll('.institution-item');

// 核心筛选函数
function filterInstitutions() {
    // 收集选中的分类ID
    const selectedCatIds = Array.from(categoryCheckboxes)
        .filter(cb => cb.checked)
        .map(cb => cb.value);
    
    // 无选中分类时隐藏所有机构
    if (selectedCatIds.length === 0) {
        institutionItems.forEach(item => item.style.display = 'none');
        return;
    }

    // 收集所有符合条件的机构ID
    const matchedInstIds = new Set();
    selectedCatIds.forEach(catId => {
        const insts = categoryInstMap[catId] || [];
        insts.forEach(inst => matchedInstIds.add(inst.id));
    });

    // 切换机构显示状态
    institutionItems.forEach(item => {
        const instId = item.dataset.instId;
        item.style.display = matchedInstIds.has(instId) ? 'block' : 'none';
    });
}

// 给分类复选框绑定变更事件
categoryCheckboxes.forEach(cb => {
    cb.addEventListener('change', filterInstitutions);
});

// 若切换到步骤3时需要触发一次筛选,可在步骤切换函数中调用filterInstitutions()
</script>

可选优化点

  • 若机构数量庞大,可改为动态生成机构DOM元素:清空institution-list后,根据匹配的机构ID实时创建元素插入,减少初始DOM体积。
  • 添加分类的“全选/全不选”按钮,提升操作效率。
  • 若分步表单有步骤切换逻辑,在切换到步骤3时主动调用一次filterInstitutions(),确保用户能看到最新筛选结果。

内容的提问来源于stack exchange,提问作者Виктор

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 18:39:59