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

如何在Django函数视图中实现分页?已掌握类视图分页方法

函数视图中实现Django分页的正确姿势

我来帮你搞定函数视图里的分页问题~你的代码里有几个关键细节没处理对,我一步步给你修正和解释:

核心问题分析

你之前的代码里先初始化了分页器,再处理过滤条件,这会导致分页的是原始的数据集,而不是你过滤后的结果,这就是分页无效的主要原因。另外,你也没有处理页码参数,也没把分页对象传递给模板。

修正后的函数视图代码

from django.core.paginator import Paginator
from django.shortcuts import render
from .models import product  # 建议把模型名改成首字母大写的Product,符合PEP8规范

def product_list_view(request):  # 函数名用小写+下划线,更符合Python编码习惯
    # 先获取基础数据集并排序,和你的类视图保持一致
    qs = product.objects.all().order_by('-pub_date')
    
    # 处理位置过滤
    location_search = request.GET.get('location')
    if location_search:  # 空字符串和None都会被自动判定为False,简化判断逻辑
        qs = qs.filter(location__contains=location_search)
    
    # 处理分类过滤(按需调整字段匹配方式,比如用exact或icontains)
    categories = request.GET.get('categories')
    if categories:
        qs = qs.filter(categories__contains=categories)
    
    # 处理价格过滤(根据你的业务需求调整,比如价格区间、小于等于等)
    price = request.GET.get('price')
    if price:
        # 示例:qs = qs.filter(price__lte=price)
        pass
    
    # 初始化分页器——这一步必须放在所有过滤操作之后!
    paginator = Paginator(qs, 5)
    # 获取当前页码,默认是第一页
    page_number = request.GET.get('page', 1)
    
    # 获取当前页的对象,get_page会自动处理无效页码(比如非数字、超出范围)
    page_obj = paginator.get_page(page_number)
    
    # 把分页对象和当前页的数据传到模板
    context = {
        'posts': page_obj.object_list,  # 当前页的商品列表
        'page_obj': page_obj  # 分页对象,用于渲染分页导航
    }
    return render(request, "products/product_list.html", context)

模板中渲染分页导航

在products/product_list.html里,除了渲染商品列表,还要添加分页导航的代码:

<!-- 商品列表展示 -->
{% for post in posts %}
    <div class="product-card">
        <h3>{{ post.title }}</h3>
        <p>位置:{{ post.location }}</p>
        <!-- 其他商品信息 -->
    </div>
{% endfor %}

<!-- 分页导航栏 -->
<div class="pagination-container">
    <span class="pagination-links">
        {% if page_obj.has_previous %}
            <a href="?page=1">&laquo; 首页</a>
            <a href="?page={{ page_obj.previous_page_number }}">上一页</a>
        {% endif %}

        <span class="current-page">
            第 {{ page_obj.number }} 页 / 共 {{ page_obj.paginator.num_pages }} 页
        </span>

        {% if page_obj.has_next %}
            <a href="?page={{ page_obj.next_page_number }}">下一页</a>
            <a href="?page={{ page_obj.paginator.num_pages }}">末页 &raquo;</a>
        {% endif %}
    </span>
</div>

进阶优化:保留过滤参数的分页链接

如果用户使用了过滤条件(比如搜索了某个位置),点击分页链接时需要保留这些参数,否则过滤条件会丢失。可以这样修改分页链接:

{% if page_obj.has_previous %}
    {% with query_params=request.GET.copy %}
        {% query_params.setlist 'page' page_obj.previous_page_number %}
        <a href="?{{ query_params.urlencode }}">上一页</a>
    {% endwith %}
{% endif %}

{% if page_obj.has_next %}
    {% with query_params=request.GET.copy %}
        {% query_params.setlist 'page' page_obj.next_page_number %}
        <a href="?{{ query_params.urlencode }}">下一页</a>
    {% endwith %}
{% endif %}

这样用户在筛选后分页,之前的过滤条件会自动保留在URL里,体验更好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 18:32:43