解决 Django 分页器在点击页码时丢失搜索过滤条件的问题,关键在于分页链接必须保留原始 GET 参数(如 g_searched),否则请求会退化为无过滤的全量查询。
解决 django 分页器在点击页码时丢失搜索过滤条件的问题,关键在于分页链接必须保留原始 get 参数(如 `g_searched`),否则请求会退化为无过滤的全量查询。
在你的 group_search.html 模板中,当前分页链接(如 ?page=2)仅传递了 page 参数,而丢弃了用户输入的 g_searched 搜索关键词。当用户点击“第2页”时,视图收到的是一个不含 g_searched 的 GET 请求,导致 request.GET.get("g_searched", 1) 返回默认值 1,进而执行 Binders.objects.filter(Q(group_id__contains=1)) —— 这不仅逻辑错误,更可能匹配大量无关记录,甚至因 1 是常见数字而返回全表数据。
✅ 正确做法:将原始搜索参数持久化到所有分页链接中。
推荐使用 Django 内置的 urlencode 过滤器动态构建带参 URL:
<!-- 在 group_search.html 中替换整个 pagination <ul> 块 --><nav aria-label="Page navigation example"> <ul class="pagination justify-content-center"> {% if page_obj.has_previous %} <li class="page-item"> <a class="page-link" href="?g_searched={{ g_searched|urlencode }}&page=1">First</a> </li> <li class="page-item"> <a class="page-link" href="?g_searched={{ g_searched|urlencode }}&page={{ page_obj.previous_page_number }}">Previous</a> </li> {% endif %} {% for num in page_obj.paginator.page_range %} <li class="page-item {% if page_obj.number == num %}active{% endif %}"> <a class="page-link" href="?g_searched={{ g_searched|urlencode }}&page={{ num }}">{{ num }}</a> </li> {% endfor %} {% if page_obj.has_next %} <li class="page-item"> <a class="page-link" href="?g_searched={{ g_searched|urlencode }}&page={{ page_obj.next_page_number }}">Next</a> </li> <li class="page-item"> <a class="page-link" href="?g_searched={{ g_searched|urlencode }}&page={{ page_obj.paginator.num_pages }}">Last</a> </li> {% endif %} </ul></nav>
? 说明:{{ g_searched|urlencode }} 确保特殊字符(如空格、&、/)被安全编码,避免 URL 解析错误;page_obj.paginator.page_range 比 "a" * num_pages 更语义清晰且健壮;active 类增强用户体验。
? 同时优化 views.py(提升健壮性与可维护性):
def group_search(request): g_searched = request.GET.get("g_searched", "").strip() # 防空格输入,避免模糊匹配 group_searched = Binders.objects.all() if g_searched: # 仅当有有效搜索词时才过滤 group_searched = group_searched.filter(group_id__icontains=g_searched) # 推荐 icontains 替代 contains paginator = Paginator(group_searched, 20) page_number = request.GET.get('page') page_obj = paginator.get_page(page_number) context = { 'g_searched': g_searched, 'page_obj': page_obj, 'group_count': group_searched.count(), # 使用过滤后 QuerySet 的 count() } return render(request, "group_search.html", context)
⚠️ 注意事项:
通过以上改造,分页链接将始终携带当前搜索上下文,确保每一页都基于相同的过滤结果集进行切片,彻底解决“翻页即重置”的核心问题。