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

Django模板中如何非硬编码生成GET请求URL?

Django分页GET请求URL动态生成方案

方法一:自定义模板标签(推荐)

这种方式能让模板代码更简洁,同时自动保留当前所有GET查询参数,仅替换page值。

  1. 创建模板标签文件
    在你的Django应用目录下新建templatetags/pagination_tags.py,写入以下代码:
from django import template
from django.urls import reverse

register = template.Library()

@register.simple_tag(takes_context=True)
def page_url(context, view_name, page_num):
    # 获取当前请求对象
    request = context['request']
    # 拷贝当前GET查询参数,避免修改原对象
    query_params = request.GET.copy()
    # 设置新的页码
    query_params['page'] = page_num
    # 生成完整URL:反向解析视图URL + 编码后的查询参数
    return f"{reverse(view_name)}?{query_params.urlencode()}"
  1. 模板中使用标签
    首先在模板顶部加载自定义标签,然后替换原有的硬编码URL:
{% load pagination_tags %}

{% if is_paginated %}
    <div class="pagination">
        <span class="page-links">
            {% if page_obj.has_previous %}
                <a href="{% page_url 'clothes:designer' page_obj.previous_page_number %}">previous</a>
            {% endif %}
            <span class="page-current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>
            {% if page_obj.has_next %}
                <a href="{% page_url 'clothes:designer' page_obj.next_page_number %}">next</a>
            {% endif %}
        </span>
    </div>
{% endif %}
  1. 确保请求上下文可用
    检查项目settings.py中TEMPLATES的context_processors是否包含django.template.context_processors.request,这样模板才能获取到request对象:
TEMPLATES = [
    {
        # ... 其他配置
        'OPTIONS': {
            'context_processors': [
                # ... 其他处理器
                'django.template.context_processors.request',
            ],
        },
    },
]

方法二:模板内直接处理(无需自定义标签)

如果不想新增模板标签,可以直接在模板中利用request.GET对象处理,但需要注意避免重复的page参数:

{% load humanize %}

{% if is_paginated %}
    <div class="pagination">
        <span class="page-links">
            {% if page_obj.has_previous %}
                {% url 'clothes:designer' as base_url %}
                {% with new_params=request.GET.copy %}
                    {% do new_params.pop 'page' None %}
                    {% do new_params.setdefault 'page' page_obj.previous_page_number %}
                    <a href="{{ base_url }}?{{ new_params.urlencode }}">previous</a>
                {% endwith %}
            {% endif %}
            <span class="page-current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>
            {% if page_obj.has_next %}
                {% url 'clothes:designer' as base_url %}
                {% with new_params=request.GET.copy %}
                    {% do new_params.pop 'page' None %}
                    {% do new_params.setdefault 'page' page_obj.next_page_number %}
                    <a href="{{ base_url }}?{{ new_params.urlencode }}">next</a>
                {% endwith %}
            {% endif %}
        </span>
    </div>
{% endif %}

注意:这里用到的{% do %}标签属于django.contrib.humanize,需要确保django.contrib.humanize已添加到INSTALLED_APPS中。

方法三:视图层传递处理后的参数

在视图函数中提前处理好分页对应的查询参数,再传递给模板:

from django.shortcuts import render
from django.core.paginator import Paginator

def designer(request):
    # 你的数据查询逻辑
    items = YourModel.objects.all()
    paginator = Paginator(items, 10)
    page_num = request.GET.get('page', 1)
    page_obj = paginator.get_page(page_num)

    # 处理上一页/下一页的查询参数
    prev_params = request.GET.copy()
    if page_obj.has_previous():
        prev_params['page'] = page_obj.previous_page_number
    next_params = request.GET.copy()
    if page_obj.has_next():
        next_params['page'] = page_obj.next_page_number

    context = {
        'page_obj': page_obj,
        'is_paginated': page_obj.has_other_pages(),
        'prev_params': prev_params.urlencode(),
        'next_params': next_params.urlencode(),
    }
    return render(request, 'your_template.html', context)

模板中直接使用:

{% if is_paginated %}
    <div class="pagination">
        <span class="page-links">
            {% if page_obj.has_previous %}
                <a href="{% url 'clothes:designer' %}?{{ prev_params }}">previous</a>
            {% endif %}
            <span class="page-current">
                Page {{ page_obj.number }} of {{ page_obj.paginator.num_pages }}.
            </span>
            {% if page_obj.has_next %}
                <a href="{% url 'clothes:designer' %}?{{ next_params }}">next</a>
            {% endif %}
        </span>
    </div>
{% endif %}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 00:04:59