如何在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">« 首页</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 }}">末页 »</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
相关产品推荐
相关产品推荐

