Django查询结果表格分页异常问题求助
Django分页后搜索条件失效的修复方案
问题根源分析
你遇到的问题本质是两个核心错误:
- 分页链接未携带搜索参数,导致翻页时丢失过滤条件,查询回到全量数据集
- 日期字段使用了错误的过滤方式,
__icontains不适用于DateTimeField类型
修复步骤
1. 修复分页链接的搜索参数传递
模板里的分页URL只传递了page参数,没有把搜索时的description、date、barcode等参数带上,导致翻页时后端无法获取之前的搜索条件,直接返回全量数据分页。
修改search_results.html中的分页链接,把所有搜索参数都附加到URL上:
<div class="d-flex justify-content-center"> <nav aria-label="Page Navigation"> {% if package_search.has_other_pages %} <ul class="pagination"> {% if package_search.has_previous %} <li class= "page-item"><a class="page-link" href='?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ package_search.previous_page_number }}'>«</a></li> {% if package_search.previous_page_number >= 11 %} <li class="page-item"><a class="page-link" href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page=1">1</a></li> <li class="page-item"><a class="page-link" href="">...</a></li> {% else %} <li class="page-item hidden"> <a href=""></a> <a href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page=1"></a> {% endif %} {% else %} </li> <li class="page-item disabled"> <span class="page-link">«</span> </li> {% endif %} {% for i in page_range %} {% if package_search.number == i %} <li class="page-item active" aria-current="page"> <span class="page-link " href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ i }}">{{i}}<span class="sr-only"></span></span> </li> {% else %} <li class="page-item"><a class="page-link bs-success-text" href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ i }}">{{ i }}</a></li> {% endif %} {% endfor %} {% if package_search.has_next %} {% if package_search.next_page_number <= last_page %} <li class="page-item"><a class="page-link" href="">...</a></li> <li class="page-item"><a class="page-link" href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ package_search.paginator.num_pages }}">{{package_search.paginator.num_pages}}</a></li> {% else %} <li class="page-item hidden"> <a href=""></a> <a href="?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ package_search.paginator.num_pages }}"></a> </li> {% endif %} <li class= "page-item"><a class="page-link" href='?description={{ description }}&date={{ date }}&barcode={{ barcode }}&employee_name={{ employee_name }}&employee_number={{ employee_number }}&page={{ package_search.next_page_number }}'>»</a></li> {% else %} <li class="page-item disabled"> <span class="page-link">»</span> </li> {% endif %} </ul> {% endif %} </nav> </div>
同时需要在views.py的search_results函数中,把所有搜索参数传入模板上下文:
context = { 'package_search': page_obj, 'navbar': 'search', 'page_range': page_range, 'last_page': last_page, 'description': description, 'date': date, 'barcode': barcode, 'employee_name': employee_name, 'employee_number': employee_number, }
2. 修复日期字段的过滤逻辑
date_created是DateTimeField,使用__icontains进行过滤是错误的,这会导致匹配到包含日期字符串的任意时间(比如2023-04-05的字符串可能匹配到2024-04-05,因为包含"04-05")。
修改views.py中的日期过滤部分:
if date: # 假设前端传入的date格式是YYYY-MM-DD filters &= Q(date_created__date=date) # 如果需要精确到当天的00:00到23:59,也可以用以下方式: # from datetime import datetime, timedelta # date_obj = datetime.strptime(date, "%Y-%m-%d").date() # filters &= Q(date_created__gte=date_obj) & Q(date_created__lt=date_obj + timedelta(days=1))
3. 清理views中的冗余分页代码
你同时使用了page_obj = paginator.get_page(page)和try-except获取package,两者功能重复,保留get_page即可(它会自动处理PageNotAnInteger和EmptyPage的情况):
# 替换原有的分页逻辑代码 page = request.GET.get('page', 1) paginator = Paginator(package_search, 12) page_obj = paginator.get_page(page) # set page_range to limit the number of page links displayed max_pages = 20 num_pages = paginator.num_pages middle_page = int(max_pages/2) if num_pages <= max_pages: page_range = range(1, num_pages+1) elif page_obj.number <= middle_page: page_range = range(1, max_pages+1) elif page_obj.number >= num_pages - middle_page: page_range = range(num_pages-max_pages+1, num_pages+1) else: page_range = range(page_obj.number-middle_page, page_obj.number+middle_page+1) last_page = paginator.num_pages - 10 context = { 'package_search': page_obj, 'navbar': 'search', 'page_range': page_range, 'last_page': last_page, 'description': description, 'date': date, 'barcode': barcode, 'employee_name': employee_name, 'employee_number': employee_number, }
验证修复效果
- 搜索2023年4月5日的数据,检查分页链接是否包含
date=2023-04-05参数 - 点击最后一页,确认所有条目都是当天的数据,不会出现后续日期的内容
- 跳转到任意页面后返回首页,验证搜索条件依然生效,只显示符合日期的结果
内容的提问来源于stack exchange,提问作者Austin
相关产品推荐
相关产品推荐

