基于Django 2.0的ERP类系统:如何实现工单表单动态列过滤?
Absolutely, Ajax is an ideal fit for this real-time filtering requirement! It lets you fetch filtered data from the server without reloading the entire page, which is exactly what you need for instant, dynamic updates as users type. Let me break down a practical implementation tailored to your Django 2.0 setup:
1. Frontend Setup (HTML + JavaScript)
First, modify your template to add filter inputs right below each table header, and wrap your table rows in an identifiable container so we can update them easily:
<table class="work-order-table"> <thead> <tr> <th>工单编号 <input type="text" class="filter-input" data-field="order_number" placeholder="过滤编号"> </th> <th>客户名称 <input type="text" class="filter-input" data-field="customer_name" placeholder="过滤客户"> </th> <!-- Add similar inputs for other columns --> </tr> </thead> <tbody id="work-orders-body"> {% for order in work_orders %} <tr> <td>{{ order.order_number }}</td> <td>{{ order.customer_name }}</td> <!-- Render other order fields here --> </tr> {% endfor %} </tbody> </table>
Next, add JavaScript to listen for input events on these filters, collect the values, and send an Ajax request to your Django backend. I'll use jQuery here for simplicity (it's widely used with Django, but you can adapt this to vanilla JS too):
$(document).ready(function() { // Debounce function to avoid spamming server with every keystroke function debounce(func, delay) { let timer; return function() { clearTimeout(timer); timer = setTimeout(func, delay); }; } const handleFilter = debounce(function() { const filters = {}; // Collect values from all filter inputs $('.filter-input').each(function() { const field = $(this).data('field'); const value = $(this).val().trim(); if (value) filters[field] = value; }); // Send Ajax request to Django filter endpoint $.ajax({ url: '/workorders/filter/', method: 'GET', data: filters, success: function(response) { // Update table body with filtered rows $('#work-orders-body').html(response); }, error: function(xhr) { console.error('Filter request failed:', xhr); } }); }, 300); // Wait 300ms after last keystroke to send request // Attach filter handler to all input fields $('.filter-input').on('input', handleFilter); });
2. Backend Django View
Create a view that handles the filter parameters, queries the WorkOrder model, and returns only the filtered table rows as an HTML snippet:
from django.shortcuts import render from .models import WorkOrder def filter_workorders(request): queryset = WorkOrder.objects.all() # Extract filter parameters from GET request order_number = request.GET.get('order_number') customer_name = request.GET.get('customer_name') # Add parameters for other columns as needed # Apply filters using case-insensitive partial matches if order_number: queryset = queryset.filter(order_number__icontains=order_number) if customer_name: queryset = queryset.filter(customer_name__icontains=customer_name) # Add filters for other columns here # Render only the table rows (using a template fragment) return render(request, 'workorders/order_rows.html', {'work_orders': queryset})
3. Template Fragment for Table Rows
Create a small template file (order_rows.html) that renders just the table rows—this keeps your code DRY and reuses the row rendering logic:
{% for order in work_orders %} <tr> <td>{{ order.order_number }}</td> <td>{{ order.customer_name }}</td> <!-- Render other order fields here --> </tr> {% endfor %}
4. URL Configuration
Add a URL pattern to map your filter view in your app's urls.py:
from django.urls import path from . import views urlpatterns = [ # Your existing URLs path('workorders/filter/', views.filter_workorders, name='filter_workorders'), ]
Extra Tips
- Debouncing: The
debouncefunction reduces unnecessary server requests by waiting until the user stops typing for 300ms before sending the filter request. - Case Insensitivity: Using
__icontainsin Django queries ensures filters work regardless of uppercase/lowercase input, which is more user-friendly. - Vanilla JS Alternative: If you prefer not to use jQuery, replace the Ajax code with the native
fetchAPI—just parse the HTML response and update the DOM manually.
This approach delivers the instant, per-column filtering you're looking for, and Ajax is perfectly suited here because it enables asynchronous, partial page updates that keep the user experience smooth and responsive.
内容的提问来源于stack exchange,提问作者Denis Callau

