基于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元素,适合简单的关键词模糊匹配:
- 添加筛选输入框:在表格上方插入输入框(示例用Bootstrap样式):
<input type="text" id="filterInput" placeholder="输入关键词筛选..." class="form-control mb-3">
- 编写筛选逻辑:在页面末尾添加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存在前端,适合复杂筛选(多条件、精确匹配、自定义规则):
- 在模板中注入JSON数据:用Django的
json_script过滤器安全序列化数据:
<script type="application/json" id="stackData"> {{ stack|json_script:"stackData" }} </script>
- 编写筛选渲染逻辑:读取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字段的不同值筛选):
- 给表格行加分类类名:在模板循环中给每行添加对应类:
<tr class="row-{{ row.name|slugify }}">
- 添加筛选下拉框:
<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>
- 控制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
相关产品推荐
相关产品推荐

