使用django-filter的FilterView和paginate_by时如何生成保留筛选参数的分页URL
解决方案
1. 分页保留筛选参数
通过自定义模板过滤器可实现自动携带所有筛选参数,无需手动逐个拼接参数:
步骤1:创建自定义模板标签
在你的APP下新建templatetags目录,新增pagination_tags.py文件,内容如下:
from django import template register = template.Library() @register.simple_tag(takes_context=True) def query_params(context, **kwargs): # 复制当前GET参数 query = context['request'].GET.copy() # 更新/移除指定参数 for k, v in kwargs.items(): if v is None: query.pop(k, None) else: query[k] = v return query.urlencode()
步骤2:修改分页链接
在模板顶部加载自定义标签:
{% load pagination_tags %}
把所有分页的href替换为以下格式,所有筛选参数会自动保留:
{% if page_obj.has_previous %} <li class="page-item"><a class="page-link" href="?{% query_params page=1 %}">First</a></li> <li class="page-item"><a class="page-link" href="?{% query_params page=page_obj.previous_page_number %}">Previous</a></li> {% else %} <li class="page-item disabled"><a class="page-link" href="#">First</a></li> <li class="page-item disabled"><a class="page-link" href="#">Previous</a></li> {% endif %} {% for page in page_obj.paginator.page_range %} {% ifequal page page_obj.number %} <li class="page-item active"><a class="page-link">{{ page }}</a></li> {% else %} <li class="page-item"><a class="page-link" href="?{% query_params page=page %}">{{ page }}</a></li> {% endifequal %} {% endfor %} {% if page_obj.has_next %} <li class="page-item"><a class="page-link" href="?{% query_params page=page_obj.next_page_number %}">Next</a></li> <li class="page-item"><a class="page-link" href="?{% query_params page=page_obj.paginator.num_pages %}">Last</a></li> {% else %} <li class="page-item disabled"><a class="page-link" href="#">Next</a></li> <li class="page-item disabled"><a class="page-link" href="#">Last</a></li> {% endif %}
2. 解决修改筛选条件后页码无效的问题
只需要在你的筛选表单内添加一个隐藏的page字段,提交新筛选条件时自动重置为第一页即可:
<form method="get"> <!-- 新增这一行 --> <input type="hidden" name="page" value="1"> <!-- 原有表单内容不变 --> {% for field in filter.form.visible_fields %} ... {% endfor %} <input type="submit" class="btn btn-block btn-primary" value="Filter"/> </form>
小优化:GET请求不需要提交CSRF Token,你可以删掉表单里的
{% csrf_token %}代码。
内容的提问来源于stack exchange,提问作者Renato Carvalho
相关产品推荐
相关产品推荐

