You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Django模板中如何保留多URL参数实现排序与分页联动?

Django 保留多URL参数的解决方案

问题场景

在Django模板中实现了排序和分页功能,但点击排序或分页链接时,只能保留page或order_by其中一个参数,无法生成同时包含多个参数的目标链接(如http://localhost:8000/list/?page=3&order_by=name)。

现有代码如下:

视图函数

def list_view(request): 
    items_list = model.objects.all() 
    # 过滤
    request_filter = request.GET.get('filter', "")
    if request_filter: 
        items_list = items_list.filter(model__icontains=request_filter)

    # 分页
    paginator = Paginator(list, 2) # 每页显示2条数据
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)
    items_list = paginator.page(page_number)

    return render(request,'list.html', {'list' : items_list, 'filter':request_filter, 'page_obj': page_obj})

模板代码

<form action="" method="GET"> 
    <input type="text"  name="filter" value={{filter}} >  
    <button class="btn btn-sm btn-outline-success" type="submit">Filtruj</button>
</form>

<table class="table">
    <thead>
        <tr>
            <th><a href="?order_by=name">Name</a></th> 
            <!-- 其他表头 -->
        </tr>
    </thead>
    <!-- 表格内容 -->
</table>

<div class="pagination">
    <span class="step-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; first</a>
            <a href="?page={{ page_obj.previous_page_number }}">previous</a>
        {% endif %}
        <!-- 分页其他部分 -->
    </span>
</div>

解决方案

方法1:模板内直接处理GET参数

利用Django模板的request.GET对象,复制现有参数后修改目标参数,自动保留其他已存在的参数。

修改排序链接

<th>
    <a href="?{% for key, value in request.GET.items %}{% if key != 'order_by' %}{{ key }}={{ value }}&{% endif %}{% endfor %}order_by=name">Name</a>
</th>

若需支持升序/降序切换,可优化为:

<th>
    {% with current_order=request.GET.get('order_by', '') %}
        {% if current_order == 'name' %}
            <a href="?{% for key, value in request.GET.items %}{% if key != 'order_by' %}{{ key }}={{ value }}&{% endif %}{% endfor %}order_by=-name">Name ↓</a>
        {% else %}
            <a href="?{% for key, value in request.GET.items %}{% if key != 'order_by' %}{{ key }}={{ value }}&{% endif %}{% endfor %}order_by=name">Name ↑</a>
        {% endif %}
    {% endwith %}
</th>

修改分页链接

{% if page_obj.has_previous %}
    <a href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page=1">&laquo; first</a>
    <a href="?{% for key, value in request.GET.items %}{% if key != 'page' %}{{ key }}={{ value }}&{% endif %}{% endfor %}page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}

方法2:视图层生成参数字典传递到模板

在视图中预处理GET参数,生成包含所有现有参数的URL编码字符串,简化模板逻辑。

修正并优化视图函数

from django.core.paginator import Paginator

def list_view(request): 
    items_list = model.objects.all() 
    # 过滤:注意把model__icontains替换为实际字段名,比如name__icontains
    request_filter = request.GET.get('filter', "")
    if request_filter: 
        items_list = items_list.filter(name__icontains=request_filter)

    # 排序
    order_by = request.GET.get('order_by', '')
    if order_by:
        items_list = items_list.order_by(order_by)

    # 分页:修复原代码错误,Paginator第一个参数应为items_list而非内置list类型
    paginator = Paginator(items_list, 2) 
    page_number = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_number)

    # 生成保留所有GET参数的URL编码字符串
    query_params = request.GET.copy()
    # 移除当前要修改的参数,避免重复
    query_params.pop('page', None)
    query_params.pop('order_by', None)

    return render(request,'list.html', {
        'page_obj': page_obj, 
        'filter': request_filter,
        'query_params': query_params.urlencode()
    })

模板中使用

排序链接:

<th>
    <a href="?{{ query_params }}&order_by=name">Name</a>
</th>

分页链接:

{% if page_obj.has_previous %}
    <a href="?{{ query_params }}&page=1">&laquo; first</a>
    <a href="?{{ query_params }}&page={{ page_obj.previous_page_number }}">previous</a>
{% endif %}

额外注意事项

  • 原视图代码中的Paginator(list, 2)是错误的,必须传入查询集items_list而非Python内置list类型。
  • 过滤条件中的model__icontains需替换为模型实际存在的字段名,否则会触发字段不存在的异常。
  • 若需处理参数重复问题,可使用query_params.setdefault()方法替代直接移除参数。

内容的提问来源于stack exchange,提问作者andrew

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 12:15:40