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

如何通过下拉选框从Django模型填充模板中的DataTables表格?

给Django+DataTables页面添加下拉过滤选框的实现方案

兄弟,我帮你搞定这个需求,咱一步步来,都是实战能用的代码:

1. 先写过滤用的Django表单

首先在你的app下创建(或修改)forms.py,定义一个下拉选框的表单。假设你的模型是YourModel,要按category字段过滤:

from django import forms
from .models import YourModel

class DataFilterForm(forms.Form):
    # 如果是关联模型用ModelChoiceField,普通字段用ChoiceField
    category = forms.ModelChoiceField(
        queryset=YourModel.objects.values_list('category', flat=True).distinct(),
        empty_label="所有分类",
        required=False
    )
    # 如果是固定选项,比如按状态过滤,可以这么写:
    # status = forms.ChoiceField(
    #     choices=[('active', '活跃'), ('inactive', '不活跃')],
    #     empty_label="所有状态",
    #     required=False
    # )

2. 视图层处理过滤逻辑

接下来修改你的视图函数(或类视图),获取表单提交的过滤值,筛选对应的QuerySet,同时把表单传给模板:

函数视图示例

from django.shortcuts import render
from .models import YourModel
from .forms import DataFilterForm

def your_table_view(request):
    form = DataFilterForm(request.GET or None)
    queryset = YourModel.objects.all()
    
    # 如果表单有效且有选择值,过滤数据
    if form.is_valid():
        category = form.cleaned_data.get('category')
        if category:
            queryset = queryset.filter(category=category)
    
    # 如果用DataTables服务器端模式,这里要处理AJAX请求,后面单独说
    return render(request, 'your_table_template.html', {
        'form': form,
        'data': queryset,
    })

类视图(ListView)示例

from django.views.generic import ListView
from .models import YourModel
from .forms import DataFilterForm

class YourTableListView(ListView):
    model = YourModel
    template_name = 'your_table_template.html'
    context_object_name = 'data'
    
    def get_queryset(self):
        queryset = super().get_queryset()
        form = DataFilterForm(self.request.GET or None)
        if form.is_valid():
            category = form.cleaned_data.get('category')
            if category:
                queryset = queryset.filter(category=category)
        return queryset
    
    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context['form'] = DataFilterForm(self.request.GET or None)
        return context

3. 模板层渲染表单+联动DataTables

在你的模板your_table_template.html里,先渲染下拉表单,再配置DataTables监听下拉框变化,自动刷新表格:

渲染表单

<!-- 放在表格上方,用BS4样式 -->
<div class="mb-3">
    <form method="get" id="filter-form">
        {{ form|crispy }} <!-- 如果用django-crispy-forms,否则手动渲染 -->
        <!-- 手动渲染的话:
        <div class="form-group">
            <label for="{{ form.category.id_for_label }}">选择分类</label>
            {{ form.category|add_class:"form-control" }}
        </div>
        -->
        <!-- 可以加个提交按钮,或者让下拉框变化就自动提交 -->
        <button type="submit" class="btn btn-primary mt-2">筛选</button>
    </form>
</div>

<!-- 你的DataTables表格 -->
<table id="your-datatable" class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>字段1</th>
            <th>字段2</th>
            <!-- 其他表头 -->
        </tr>
    </thead>
    <tbody>
        {% for item in data %}
        <tr>
            <td>{{ item.field1 }}</td>
            <td>{{ item.field2 }}</td>
            <!-- 其他字段 -->
        </tr>
        {% endfor %}
    </tbody>
</table>

DataTables联动配置(客户端模式)

如果数据量不大,用客户端模式就够了,监听下拉框变化,重新加载页面或用DataTables的搜索过滤:

$(document).ready(function() {
    var table = $('#your-datatable').DataTable({
        "paging": true,
        "searching": true,
        "ordering": true,
        "info": true,
        "autoWidth": false,
        "bootstrap": true // 启用BS4样式
    });

    // 监听下拉框变化,自动提交表单刷新页面
    $('#id_category').on('change', function() {
        $('#filter-form').submit();
    });

    // 或者不用刷新页面,用DataTables客户端过滤(适合小数据)
    // $('#id_category').on('change', function() {
    //     var filterValue = $(this).val();
    //     table.column(2).search(filterValue).draw(); // 假设category对应第3列(索引从0开始)
    // });
});

大数据量?用DataTables服务器端模式

如果数据量很大,建议用服务器端处理,这时候视图要处理AJAX请求,返回JSON格式的数据:

修改视图处理AJAX

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

def your_table_ajax_view(request):
    # 获取DataTables发送的参数
    draw = int(request.GET.get('draw', 1))
    start = int(request.GET.get('start', 0))
    length = int(request.GET.get('length', 10))
    search_value = request.GET.get('search[value]', '')
    # 获取过滤参数
    category = request.GET.get('category', '')

    queryset = YourModel.objects.all()

    # 应用下拉过滤
    if category:
        queryset = queryset.filter(category=category)
    # 应用全局搜索
    if search_value:
        queryset = queryset.filter(
            Q(field1__icontains=search_value) | Q(field2__icontains=search_value)
        )

    # 排序
    order_column = request.GET.get('order[0][column]', 0)
    order_dir = request.GET.get('order[0][dir]', 'asc')
    columns = ['field1', 'field2'] # 对应表格列的字段名
    queryset = queryset.order_by(f'{order_dir}{columns[int(order_column)]}')

    # 分页
    total_records = queryset.count()
    filtered_records = queryset.count()
    data = queryset[start:start+length]

    # 构造返回的JSON数据
    response = {
        'draw': draw,
        'recordsTotal': total_records,
        'recordsFiltered': filtered_records,
        'data': [
            [item.field1, item.field2] for item in data
        ]
    }
    return JsonResponse(response)

修改模板的DataTables配置

$(document).ready(function() {
    var table = $('#your-datatable').DataTable({
        "serverSide": true,
        "ajax": {
            "url": "{% url 'your_ajax_view_name' %}",
            "data": function(d) {
                // 把下拉框的过滤值传给服务器
                d.category = $('#id_category').val();
            }
        },
        "columns": [
            {"data": 0},
            {"data": 1}
            // 对应视图返回的data数组的索引
        ],
        "paging": true,
        "searching": true,
        "ordering": true,
        "info": true,
        "autoWidth": false,
        "bootstrap": true
    });

    // 下拉框变化时,重新加载表格数据
    $('#id_category').on('change', function() {
        table.draw();
    });
});

最后几个小提示

  • 如果用django-crispy-forms,表单样式会自动适配BS4,省很多事
  • 记得在urls.py里配置对应的视图路由,尤其是AJAX视图
  • 测试的时候要注意空选项的处理,确保用户选“所有分类”时能显示全部数据

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:40:35