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

在Django渲染模板中实现实时搜索功能

Django 表格实时全量搜索实现方案

针对你现有基于Django分页渲染的表格,要实现覆盖所有分页数据的实时搜索,提供两种实用方案,按需选择:


方案一:前端全量加载+JS过滤(适合小数据量场景)

核心思路是把所有数据一次性传到前端,通过JavaScript监听搜索输入,实时过滤并渲染符合条件的表格行,无需频繁请求后端。

步骤1:修改Django视图

保留原有分页逻辑的同时,将全量数据序列化为JSON传给模板:

from django.core import serializers
from django.core.paginator import Paginator
from django.shortcuts import render
from .models import YourModel  # 替换成你的模型类

def your_table_view(request):
    # 获取全量数据
    full_queryset = YourModel.objects.all()
    # 原有分页逻辑
    paginator = Paginator(full_queryset, 10)  # 每页10条,可调整
    page_number = request.GET.get('page')
    page_obj = paginator.get_page(page_number)
    # 序列化全量数据为JSON
    full_data_json = serializers.serialize('json', full_queryset)
    
    return render(request, 'your_table_template.html', {
        'page_obj': page_obj,
        'full_data': full_data_json
    })

步骤2:更新模板代码

添加搜索框,保留原有表格和分页控件,新增JS实现过滤逻辑:

<!-- 搜索输入框 -->
<input type="text" id="search-input" class="mb-3 p-2" placeholder="输入关键词搜索所有数据...">

<!-- 原有表格 -->
<table class="table table-bordered">
  <thead>
    <tr>
      <th>字段1</th>
      <th>字段2</th>
      <!-- 替换为你的表格列 -->
    </tr>
  </thead>
  <tbody id="table-body">
    {% for item in page_obj %}
    <tr>
      <td>{{ item.field1 }}</td>
      <td>{{ item.field2 }}</td>
      <!-- 替换为你的模型字段 -->
    </tr>
    {% endfor %}
  </tbody>
</table>

<!-- 原有分页控件 -->
<div class="pagination mt-3">
  <span class="step-links">
    {% if page_obj.has_previous %}
      <a href="?page=1">&laquo; 首页</a>
      <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
    {% endif %}
    <span class="current">
      第 {{ page_obj.number }} 页 / 共 {{ page_obj.paginator.num_pages }} 页
    </span>
    {% if page_obj.has_next %}
      <a href="?page={{ page_obj.next_page_number }}">下一页</a>
      <a href="?page={{ page_obj.paginator.num_pages }}">末页 &raquo;</a>
    {% endif %}
  </span>
</div>

<script>
// 初始化数据
const fullData = JSON.parse('{{ full_data|escapejs }}');
const tableBody = document.getElementById('table-body');
const searchInput = document.getElementById('search-input');
const originalPageRows = tableBody.innerHTML; // 保存初始分页内容

// 生成表格行的工具函数
function buildTableRows(items) {
  let html = '';
  items.forEach(item => {
    const fields = item.fields;
    html += `
      <tr>
        <td>${fields.field1}</td>
        <td>${fields.field2}</td>
        <!-- 对应你的模型字段 -->
      </tr>
    `;
  });
  return html;
}

// 搜索监听逻辑
searchInput.addEventListener('input', function() {
  const keyword = this.value.trim().toLowerCase();
  if (!keyword) {
    // 清空搜索时恢复初始分页内容
    tableBody.innerHTML = originalPageRows;
    return;
  }
  // 过滤全量数据:检查所有字段是否包含关键词
  const filteredItems = fullData.filter(item => {
    return Object.values(item.fields).some(value => 
      String(value).toLowerCase().includes(keyword)
    );
  });
  // 渲染过滤后的结果
  tableBody.innerHTML = buildTableRows(filteredItems);
});
</script>

方案二:后端AJAX动态搜索(适合大数据量场景)

核心思路是通过AJAX向后端发送搜索请求,由数据库查询符合条件的所有数据,避免前端加载大量数据,性能更优。

步骤1:新增AJAX搜索视图

from django.http import JsonResponse
from django.db.models import Q
from .models import YourModel

def search_table_data(request):
    keyword = request.GET.get('keyword', '').strip()
    # 构建多字段模糊查询条件
    query = Q()
    # 替换为需要搜索的字段列表
    search_fields = ['field1', 'field2', 'field3']
    for field in search_fields:
        query |= Q(**{f"{field}__icontains": keyword})
    
    # 获取符合条件的数据,返回指定字段
    results = list(YourModel.objects.filter(query).values(*search_fields))
    return JsonResponse({'items': results})

步骤2:配置路由

在urls.py中添加搜索路由:

from django.urls import path
from . import views

urlpatterns = [
    path('table/', views.your_table_view, name='table-page'),
    path('table/search/', views.search_table_data, name='table-search'),
]

步骤3:更新模板代码

添加搜索框,保留原有表格和分页,新增AJAX请求逻辑:

<!-- 搜索输入框 -->
<input type="text" id="search-input" class="mb-3 p-2" placeholder="输入关键词搜索所有数据...">

<!-- 原有表格 -->
<table class="table table-bordered">
  <thead>
    <tr>
      <th>字段1</th>
      <th>字段2</th>
      <!-- 替换为你的表格列 -->
    </tr>
  </thead>
  <tbody id="table-body">
    {% for item in page_obj %}
    <tr>
      <td>{{ item.field1 }}</td>
      <td>{{ item.field2 }}</td>
      <!-- 替换为你的模型字段 -->
    </tr>
    {% endfor %}
  </tbody>
</table>

<!-- 原有分页控件 -->
<div class="pagination mt-3">
  <!-- 保留原有分页代码 -->
</div>

<script>
const tableBody = document.getElementById('table-body');
const searchInput = document.getElementById('search-input');
const originalPageRows = tableBody.innerHTML;

// 防抖函数:减少频繁请求
function debounce(func, delay = 300) {
  let timeoutId;
  return function(...args) {
    clearTimeout(timeoutId);
    timeoutId = setTimeout(() => func.apply(this, args), delay);
  };
}

// 执行搜索请求
const performSearch = debounce(function() {
  const keyword = searchInput.value.trim();
  if (!keyword) {
    tableBody.innerHTML = originalPageRows;
    return;
  }
  // 发送AJAX请求
  fetch(`{% url 'table-search' %}?keyword=${encodeURIComponent(keyword)}`)
    .then(res => res.json())
    .then(data => {
      let html = '';
      data.items.forEach(item => {
        html += `
          <tr>
            <td>${item.field1}</td>
            <td>${item.field2}</td>
            <!-- 对应你的字段 -->
          </tr>
        `;
      });
      tableBody.innerHTML = html;
    })
    .catch(err => console.error('搜索失败:', err));
});

// 监听输入事件
searchInput.addEventListener('input', performSearch);
</script>

注意事项

  • 小数据量(≤5000条)选方案一,实现简单;大数据量选方案二,避免前端内存占用过高。
  • 若需要精确搜索,可修改过滤条件(比如去掉toLowerCase(),或者调整数据库查询的__icontains为__exact)。
  • 方案二中的防抖函数可调整延迟时间,平衡实时性和请求频率。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 04:27:09