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

如何在Django3.2中实现无需提交按钮、支持AJAX的多选复选框过滤功能

Django 复选框多选联动AJAX无刷新筛选实现方案

开发环境:Python 3.9 + Django 3.2


1. 前端模板修改

首先调整原有表单,移除提交按钮,新增产品列表渲染容器用于动态更新筛选结果:

<form method="post" id="category-box">
  {% csrf_token %}
  {% for c in category_list %}
  <div class="form-check">
    <input class="form-check-input" type="checkbox" name="category" value="{{c.name}}" id="{{c.name}}">
    <label class="form-check-label" for="{{c.name}}">
      <a href="{{ c.get_absolute_url }}">{{ c.name }}</a>
    </label>
  </div>
  {% endfor %}
</form>

<!-- 动态更新的产品列表容器 -->
<div id="product-list-container">
  {% include "product_list_partial.html" %}
</div>

相比缓存参数追加的方案,后续采用每次全量收集已选值的逻辑,更简洁且能兼容用户取消勾选的操作,避免参数缓存错乱


2. JS交互逻辑实现

用原生JS实现复选框事件监听、参数收集和AJAX请求:

// 初始化DOM元素
const checkboxes = document.querySelectorAll('input[name="category"]');
const csrfToken = document.querySelector('[name=csrfmiddlewaretoken]').value;
const productContainer = document.getElementById('product-list-container');

// 给所有复选框绑定选中变化事件
checkboxes.forEach(checkbox => {
  checkbox.addEventListener('change', function() {
    // 全量收集所有已勾选的分类值
    const selectedCategories = Array.from(checkboxes)
      .filter(item => item.checked)
      .map(item => item.value);
    
    // 发送筛选请求
    fetch(window.location.href, {
      method: 'POST',
      headers: {
        'X-CSRFToken': csrfToken,
        'Content-Type': 'application/x-www-form-urlencoded',
        'X-Requested-With': 'XMLHttpRequest' // 标记为AJAX请求,方便后端识别
      },
      body: `category=${encodeURIComponent(JSON.stringify(selectedCategories))}`
    })
    .then(res => res.text())
    .then(html => {
      // 替换页面产品列表内容
      productContainer.innerHTML = html;
    })
    .catch(err => console.error('筛选请求失败:', err));
  });
});

3. 后端视图逻辑调整

修改原产品列表视图,识别AJAX请求时返回局部模板内容:

from django.shortcuts import render
from .models import Product, Category
import json

def product_list(request):
    products = Product.objects.all()
    categories = Category.objects.all()
    
    # 处理AJAX筛选请求
    if request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest':
        if request.POST.get('category'):
            selected_cats = json.loads(request.POST.get('category'))
            if selected_cats:
                # 按选中的分类筛选产品
                products = products.filter(category__name__in=selected_cats)
        # 仅返回产品列表的局部HTML
        return render(request, 'product_list_partial.html', {'products': products})
    
    # 普通页面请求返回完整页面
    return render(request, 'product_list.html', {
        'products': products,
        'category_list': categories
    })

4. 新增产品列表局部模板

新建product_list_partial.html,仅编写产品列表渲染代码即可:

{% for product in products %}
<div class="product-item">
  <h3>{{ product.name }}</h3>
  <p>分类:{{ product.category.name }}</p>
  <p>价格:¥{{ product.price }}</p>
  <!-- 其他产品自定义字段 -->
</div>
{% empty %}
<p>暂无符合筛选条件的产品</p>
{% endfor %}

注意事项

  • 局部模板不要包含页面头尾、公共CSS/JS等内容,仅保留产品列表本身的HTML结构
  • 如果需要扩展价格、销量等其他筛选条件,只需在JS收集参数时新增对应字段取值,后端同步补充筛选逻辑即可
  • 未勾选任何分类时默认返回全部产品,可根据业务需求调整该逻辑

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 02:36:04