如何为Pandas DataFrame实现Django分页并在模板正常显示?
问题原因
你的代码存在两个核心问题,导致表格无内容、分页不生效:
- 模板中写的
query.iterrows是pandas的实例方法对象,Django模板引擎不支持自动给方法加括号执行,不会返回可遍历的行迭代器,所以循环根本没有运行。 - 你虽然生成了分页后的
page_obj对象,但没有将其传递给模板,反而传入了全量未分页的queryDataFrame,就算遍历逻辑正常,也不会展示分页后的数据。
修复方案
1. 调整views.py逻辑
把DataFrame转成模板兼容性更好的原生字典列表再做分页,同时把当前页数据、分页对象传入上下文:
def get_context_data(self, **kwargs): ... df = pd.DataFrame(list(Case.objects.all().values(...))) query = df.assign(cnt=1).groupby([...])['cnt'].sum().reset_index() # 将DataFrame转成 每行一个字典 的列表结构,适配Django模板和Paginator paginator = Paginator(query.to_dict("records"), 10) # 直接给page参数设置默认值1,无需单独判断None page_number = self.request.GET.get("page", 1) page_obj = paginator.page(int(page_number)) context["page_obj"] = page_obj # 只传当前页的行数据到模板,不要传全量数据 context["rows"] = page_obj.object_list return context
2. 调整模板代码
去掉pandas专属的iterrows调用,直接遍历传入的当前页行数据,可额外加分页导航组件:
<table class="table table-bordered" > <tbody> {% for row in rows %} <tr> {% for cell in row.values %} <td> {{cell}} </td> {% endfor %} </tr> {% endfor %} </tbody> </table> <!-- 分页导航栏 --> <div class="pagination"> <span class="step-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_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>
关键注意点
- 不要在Django模板中调用需要加括号才能执行的Python方法,模板引擎没有自动执行方法的逻辑,只会把方法本身当成普通变量处理,无法遍历。
- Pandas的自定义数据结构在Django模板中遍历容易出现兼容问题,提前转成字典、列表等Python原生数据结构是最稳妥的处理方式。
- 分页场景下只需要把当前页的数据传给模板即可,不需要传全量数据集,既能避免渲染问题,也能提升页面加载性能。
内容的提问来源于stack exchange,提问作者edche
相关产品推荐
相关产品推荐

