Django Paginator报错:__init__()缺少number和paginator必填参数
解决Django分页中的
__init__() missing required arguments错误 嘿,我看了你遇到的分页问题,这个错误其实是模板里的一个小笔误导致的,咱们一步步来搞定它:
错误根源:模板变量名写错了
看你模板里的这一行代码:
<a href="?page={{ products.previous_page_number }}">previous</a>
这里你用了products作为变量名,但后端视图传递给模板的分页对象是productsList,而且你在视图里已经把列表转换成了Django的Page对象。把这一行改成:
<a href="?page={{ productsList.previous_page_number }}">previous</a>
这个参数缺失的错误就会消失了——因为Django的Page对象需要依赖number和paginator属性,你写错变量名后,模板找不到正确的Page对象,就会抛出这个异常。
额外的优化建议
除了修复笔误,还有几个地方可以优化,让代码更健壮:
统一变量命名:你视图里的变量一会儿是
products_List(带下划线),一会儿模板用productsList(驼峰),建议统一成符合Python规范的products_list,避免后续再出现类似的命名混淆。解决N+1查询问题:你现在的代码先取100个
Products,然后循环每个产品去查对应的Books,这会触发101次数据库查询(1次查Products,100次查Books),性能很差。如果Products和Books是一对一关联的,你可以用select_related一次性关联查询:
# 假设Books和Products是一对一关系,通过productid关联 products_list = Books.objects.select_related('products').order_by('productid')[:100]
这样就能一次性把所有需要的数据查出来,大幅提升页面加载速度。
- 简化分页逻辑:Django的
Paginator提供了get_page()方法,可以自动处理非法页码(比如非整数、超出范围的页码),不用自己写try-except块,代码更简洁:
from django.core.paginator import Paginator def products(request): # 优化后的查询 products_list = Books.objects.select_related('products').order_by('productid')[:100] paginator = Paginator(products_list, 10) # get_page自动处理异常,返回正确页面 products_page = paginator.get_page(request.GET.get('page')) return render( request, 'catalog/products.html', {'productsList': products_page} )
最后,确保模板里所有分页相关的变量都用productsList(或者你统一后的变量名),完整的模板代码应该是这样的:
<div class="pagination"> <span class="step-links"> {% if productsList.has_previous %} <a href="?page=1">« first</a> <a href="?page={{ productsList.previous_page_number }}">previous</a> {% endif %} <span class="current"> Page {{ productsList.number }} of {{ productsList.paginator.num_pages }}. </span> {% if productsList.has_next %} <a href="?page={{ productsList.next_page_number }}">next</a> <a href="?page={{ productsList.paginator.num_pages }}">last »</a> {% endif %} </span> </div>
内容的提问来源于stack exchange,提问作者sly_Chandan
相关产品推荐
相关产品推荐

