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

基于Django实现可筛选表格的最优方案咨询

问题描述

我用Django模板做了一个包含HTML表格和PDF预览iframe的页面,已经完成表格条目和单/多个PDF的匹配功能。现在要给表格加数据筛选功能,不想用现成的Django库(想自己实现,处于学习阶段),也不想每次筛选都重新请求数据库,希望直接用页面已加载的数据。请问有哪些可行的实现思路?


最小可复现示例

stack.html

{% extends "website/base.html" %}
{% block content %}
{% load static %}
<link rel="stylesheet" type="text/css" href="{% static 'evidence/css/style.css' %}">
<div class="container">
    {% csrf_token %}
    <div class="row">
        <div class="col-8">
            <div class="row">
                <div class="col-12">
                    <table class="table">
                        <thead class="table-dark">
                            <tr>
                                <td>name</td>
                                <td>hash</td>
                                <td>something</td>
                            </tr>
                        </thead>
                        <tbody>
                            {% for row in stack %}
                            <tr>
                                <td>{{ row.name }}</td>
                                <td>{{ row.hash }}</td>
                                <td>{{ row.something }}</td>
                            </tr>
                            {% endfor %}
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </div>
</div>
{% endblock %}

视图函数(views.py)

def stack(request):
    context = Stack.objects.all()
    return render(request, "evidence/stack.html", {"stack": context})

URL配置(urls.py)

app_name = "evidence"
urlpatterns = [
    # ... 其他URL规则
    path('stack', stack, name='stack'),
]

模型(models.py)

class Stack(models.Model):
    name = models.CharField(max_length=150)
    hash = models.CharField(max_length=150)
    something = models.CharField(max_length=150)

可行实现方向

核心思路是基于前端已加载的数据做本地筛选,全程无需后端参与、不请求数据库,以下是几种具体方案:

方案1:纯DOM操作实时筛选

直接操作表格DOM元素,适合简单的关键词模糊匹配:

  1. 添加筛选输入框:在表格上方插入输入框(示例用Bootstrap样式):
<input type="text" id="filterInput" placeholder="输入关键词筛选..." class="form-control mb-3">
  1. 编写筛选逻辑:在页面末尾添加JavaScript代码,监听输入事件并控制行的显示/隐藏:
document.getElementById('filterInput').addEventListener('input', function(e) {
    const filterText = e.target.value.toLowerCase();
    const tableRows = document.querySelectorAll('table tbody tr');
    
    tableRows.forEach(row => {
        // 获取当前行所有文本内容
        const rowText = row.textContent.toLowerCase();
        // 匹配则显示,否则隐藏
        row.style.display = rowText.includes(filterText) ? '' : 'none';
    });
});

如果需要按指定列筛选(比如只匹配name列),可以修改为只读取对应单元格的文本:

const nameCell = row.querySelector('td:first-child');
const rowText = nameCell.textContent.toLowerCase();

方案2:基于JSON数据重渲染表格

把后端数据转成JSON存在前端,适合复杂筛选(多条件、精确匹配、自定义规则):

  1. 在模板中注入JSON数据:用Django的json_script过滤器安全序列化数据:
<script type="application/json" id="stackData">
    {{ stack|json_script:"stackData" }}
</script>
  1. 编写筛选渲染逻辑:读取JSON数据,根据筛选条件重新生成表格内容:
// 读取初始数据
const stackData = JSON.parse(document.getElementById('stackData').textContent);
const tbody = document.querySelector('table tbody');

document.getElementById('filterInput').addEventListener('input', function(e) {
    const filterText = e.target.value.toLowerCase();
    // 多字段筛选
    const filteredData = stackData.filter(item => {
        return item.name.toLowerCase().includes(filterText) 
            || item.hash.toLowerCase().includes(filterText)
            || item.something.toLowerCase().includes(filterText);
    });
    // 清空表格并重新渲染
    tbody.innerHTML = '';
    filteredData.forEach(item => {
        const tr = document.createElement('tr');
        tr.innerHTML = `
            <td>${item.name}</td>
            <td>${item.hash}</td>
            <td>${item.something}</td>
        `;
        tbody.appendChild(tr);
    });
});

这种方式可以轻松扩展多条件筛选(比如加下拉框选择筛选列、添加精确匹配开关等)。

方案3:结合CSS类做分类筛选

适合按固定值做分类筛选(比如按name字段的不同值筛选):

  1. 给表格行加分类类名:在模板循环中给每行添加对应类:
<tr class="row-{{ row.name|slugify }}">
  1. 添加筛选下拉框:
<select id="categoryFilter" class="form-control mb-3">
    <option value="all">全部</option>
    {% for row in stack %}
        <option value="{{ row.name|slugify }}">{{ row.name }}</option>
    {% endfor %}
</select>
  1. 控制CSS类显示:用JavaScript切换行的隐藏类(示例用Bootstrap的d-none类):
document.getElementById('categoryFilter').addEventListener('change', function(e) {
    const selectedValue = e.target.value;
    const tableRows = document.querySelectorAll('table tbody tr');
    
    tableRows.forEach(row => {
        if (selectedValue === 'all') {
            row.classList.remove('d-none');
        } else {
            row.classList.toggle('d-none', !row.classList.contains(`row-${selectedValue}`));
        }
    });
});

注意事项
  • 以上方案均为纯前端实现,不会发起新的数据库请求,符合需求。
  • 如果数据量极大(上万条),前端筛选可能有性能损耗,中小规模数据完全够用。
  • 可根据需求组合多种筛选方式(比如关键词筛选+分类筛选)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 12:37:34