Django使用RawQuerySet分页报错:object of type 'RawQuerySet' has no len()如何解决?
解决Django中RawQuerySet分页时的
object of type 'RawQuerySet' has no len()错误 嘿,我之前也踩过这个坑!你遇到的这个错误,核心原因是Django的RawQuerySet没有实现__len__方法——而我们常用的Paginator分页组件在计算总页数时,会默认尝试调用len()来获取数据集的总数,这就导致了冲突。下面给你两个靠谱的解决方案:
方案一:手动计算总数(推荐,性能友好)
因为RawQuerySet是直接执行原始SQL,Django没办法自动帮我们统计总数,所以我们可以自己写一个统计总数的SQL,然后把总数手动传给Paginator。这样既避免了加载全部数据,又能正常分页。
示例代码:
from django.core.paginator import Paginator from django.shortcuts import render from your_app.models import YourModel def your_view(request): # 1. 定义你的业务查询SQL和参数 main_sql = "SELECT * FROM your_app_yourmodel WHERE status = %s ORDER BY created_at DESC" query_params = ["active"] # 2. 编写对应的统计总数SQL(注意过滤条件要和主查询完全一致!) count_sql = "SELECT COUNT(*) AS count FROM your_app_yourmodel WHERE status = %s" # 执行count查询,获取总数 total_count = YourModel.objects.raw(count_sql, query_params)[0].count # 3. 获取原始查询结果 raw_results = YourModel.objects.raw(main_sql, query_params) # 4. 初始化分页器,手动传入count参数 paginator = Paginator(raw_results, per_page=10, count=total_count) page_num = request.GET.get("page", 1) page_obj = paginator.get_page(page_num) return render(request, "your_template.html", {"page_obj": page_obj})
方案二:转换为列表(仅适合小数据量场景)
如果你的数据集很小,也可以直接把RawQuerySet转换成Python列表——列表是支持len()的,这样分页器就能正常工作。但要注意:如果数据量很大,这种方式会把所有数据加载到内存,严重影响性能,所以谨慎使用。
示例代码:
from django.core.paginator import Paginator from your_app.models import YourModel def your_view(request): raw_sql = "SELECT * FROM your_app_yourmodel WHERE category = %s" query_params = ["tech"] # 转换为列表 result_list = list(YourModel.objects.raw(raw_sql, query_params)) paginator = Paginator(result_list, per_page=10) page_num = request.GET.get("page", 1) page_obj = paginator.get_page(page_num) return render(request, "your_template.html", {"page_obj": page_obj})
关键提醒
- 用方案一时,count SQL的过滤条件必须和主查询完全匹配,否则统计出来的总数会和实际分页数据不一致,导致分页逻辑出错。
- 尽量优先选择方案一,尤其是数据量大的场景,避免方案二带来的内存占用问题。
内容的提问来源于stack exchange,提问作者Ali Soltani
相关产品推荐
相关产品推荐

