Django使用Paginator分页访问/products/页报ModelBase无len()的TypeError
错误根因与解决方案
核心错误触发点
报错本质是Paginator初始化时接收到了Book模型类(Django中属于ModelBase类型的对象),而非可迭代、可计算长度的数据集。Paginator初始化时需要对传入对象计算总长度以推导总页数,而模型类本身没有实现__len__方法,因此触发object of type 'ModelBase' has no len()的类型错误。
具体修正点
- 修正
Paginator的传入参数:将原本传入模型类Book的写法,替换为传入模型查询集Book.objects.all(),这才是分页器需要处理的数据源 - 增加页码参数的容错处理:从URL获取的
page参数是字符串类型,且可能存在非数字、超出总页数范围的情况,直接传入分页方法会触发新的报错,需要增加异常捕获逻辑 - 修正模板内的分页逻辑错误:
- 原模板中判断是否有上一页的代码引用了未定义的
listing变量,应该替换为实际传入的分页对象books - 原模板中上一页链接的页码值错误引用了循环内的单本书籍对象
book的属性,应该替换为分页对象books的previous_page_number属性
- 原模板中判断是否有上一页的代码引用了未定义的
修正后的视图代码
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage def showproducts(request): oof = CartItem.objects.filter(user=request.user).values_list('book', flat=True) lmao = OrderItem.objects.filter(user=request.user).values_list('book', flat=True) hehe = CartItem.objects.filter(user=request.user) category = Category.objects.all() # 正确传入模型查询集作为分页数据源 all_books = Book.objects.all() paginator = Paginator(all_books, 2) page_num = request.GET.get('page') # 异常捕获处理非法页码 try: books = paginator.page(page_num) except PageNotAnInteger: # 页码非数字时默认展示第一页 books = paginator.page(1) except EmptyPage: # 页码超出范围时展示最后一页 books = paginator.page(paginator.num_pages) final_price = 0 for item in hehe: final_price += item.book.price return render(request, 'main/products.html', { 'books': books, 'price': final_price, 'cart': oof, 'order': lmao, 'category': category })
模板侧需要替换的分页代码段
{% if books.has_other_pages %} {% if books.has_previous %} <li class="page-item"> <a href="?page={{ books.previous_page_number }}" class="page-link">«</a> </li> {% else %} <li class="page-item disabled"> <a class="page-link">«</a> </li> {% endif %} {% for i in books.paginator.page_range %} {% if books.number == i %} <li class="page-item active"> <a class="page-link">{{i}}</a> </li> {% else %} <li class="page-item"> <a href="?page={{i}}" class="page-link">{{i}}</a> </li> {% endif %} {% endfor %} {% if books.has_next %} <li class="page-item"> <a href="?page={{books.next_page_number}}" class="page-link">»</a> </li> {% else %} <li class="page-item disabled"> <a class="page-link">»</a> </li> {% endif %} {% endif %}
内容的提问来源于stack exchange,提问作者Arpit Linux
相关产品推荐
相关产品推荐

