Django结合Ajax实现QuerySet动态过滤及get_queryset参数缺失问题解决
报错原因
你自定义了get_queryset方法要求传入query参数,但Django的ListView内部默认会无参数调用get_queryset来渲染初始页面,所以直接触发参数缺失报错。
修复后的完整实现方案
1. 视图(View)修改
from django.shortcuts import render from django.http import JsonResponse class ManageUserView(SuperUserRequired, ListView): model = User template_name = 'webapp/klant/beheerklant.html' def get_queryset(self): # 从请求参数中取搜索关键词,兼容GET初始加载和POST的AJAX请求 query = self.request.POST.get('query', '') or self.request.GET.get('q', '') # 过滤规则保持不变 object_list = self.model.objects.filter(contactNaam__icontains=query).exclude(is_superuser=True) return object_list def post(self, request, *args, **kwargs): # 拿到过滤后的数据集 object_list = self.get_queryset() # 渲染表格行片段,返回给前端直接替换 html = render( request, 'webapp/klant/partials/klant_table_rows.html', {'object_list': object_list} ).content.decode('utf-8') return JsonResponse({'html': html})
2. 模板(Template)调整
首先新建片段模板 webapp/klant/partials/klant_table_rows.html,内容就是你原来的表格行逻辑:
{% if object_list %} {% for user in object_list %} <tr> <td>{{ user.bedrijfsNaam }}</td> <td>{{ user.contactNaam }}</td> <td>{{ user.adres }}</td> <td> <a href="{% url 'klantupdaten' user.id %}"><i class="fas fa-edit"></i></a> <a href="#" data-url="{% url 'klantverwijderen' user.id %}" class="deletegebruiker" data-bs-toggle="modal" data-bs-target="#dynamic-modal"><i class="fas fa-trash-alt"></i></a> </td> </tr> {% endfor %} {% else %} <tr> <td colspan="4"> <p>Geen gebruikers gevonden</p> <p> <a href="{% url 'klantaanmaken' user.id %}" class="btn btn-primary">Maak klant aan</a> </p> </td> </tr> {% endif %}
然后修改原来的主模板,把tbody部分替换成引入片段,同时给tbody加个id方便JS定位:
<!-- 其他代码保持不变 --> <tbody id="klant-table-body"> {% include 'webapp/klant/partials/klant_table_rows.html' %} </tbody> <!-- 其他代码保持不变 -->
另外修正你原来form的属性错误,把<form action="" form="get">改成<form action="" method="get">
3. jQuery代码修改
$('.zoekklanten').on('keyup', function(){ var url = $(this).data('url') var query = $(this).val(); $.ajax({ url: url, type: 'POST', data: { 'query': query }, dataType: 'json', beforeSend: function(xhr, settings){ if(!csrfSafeMethod(settings.type) && !this.crossDomain){ xhr.setRequestHeader("X-CSRFToken", csrftoken); } }, success: function(result){ // 直接替换表格内容 $('#klant-table-body').html(result.html); }, error: function(data){ console.error('搜索请求失败', data); } }) // 阻止表单默认提交 return false; })
额外优化建议
- 可以加个防抖逻辑,避免用户输入时每按一个键就发一次请求,降低服务器压力
- 如果搜索数据量很大,可以加个加载状态提示,提升用户体验
内容的提问来源于stack exchange,提问作者Swauters
相关产品推荐
相关产品推荐

