
Django 模板中分页导航未渲染,根本原因是视图传递的分页对象名为 pr,但模板错误地使用了未定义的变量 products 来访问分页信息;只需统一使用上下文键 pr 即可修复。
django 模板中分页导航未渲染,根本原因是视图传递的分页对象名为 `pr`,但模板错误地使用了未定义的变量 `products` 来访问分页信息;只需统一使用上下文键 `pr` 即可修复。
在 Django 中实现分页功能时,视图层与模板层的变量命名必须严格一致,否则分页器将无法正常渲染。从你提供的代码可见:views.py 中通过 render(request, 'index.html', {'ct': cat, 'pr': products}) 将分页后的数据以键 'pr' 传入模板;然而在 index.html 中,分页导航部分却错误地引用了未声明的 products 变量:
<!-- ❌ 错误写法:products 在模板中未定义 -->
{% for pg in products.paginator.page_range %}
<a href="?page=%7B%7Bpg%7D%7D">{{pg}}</a>
{% endfor %}
这会导致模板引擎静默失败(不报错但不渲染),因为 products 是 Python 层变量名,并未注入到模板上下文中。
✅ 正确做法是:始终使用视图中传入的上下文键 pr —— 它才是模板可访问的分页对象(即 Page 实例):
<!-- ✅ 正确写法:使用上下文键 'pr' -->
<div class="mx-auto">
<div class="text-center">
{% for pg in pr.paginator.page_range %}
<a href="?page=%7B%7B%20pg%20%7D%7D" class="btn btn-light btn-sm {% if pr.number == pg %}active{% endif %}">
{{ pg }}
</a>
{% endfor %}
<!-- ✨ 增强体验:添加上一页/下一页按钮 -->
{% if pr.has_previous %}
<a href="?page=%7B%7B%20pr.previous_page_number%20%7D%7D" class="btn btn-outline-secondary btn-sm">« 上一页</a>
{% endif %}
{% if pr.has_next %}
<a href="?page=%7B%7B%20pr.next_page_number%20%7D%7D" class="btn btn-outline-secondary btn-sm">下一页 »</a>
{% endif %}
</div>
</div>
同时,请确保产品列表循环也使用 pr.object_list(而非原始 prodt),以保证展示内容与当前页匹配:
<!-- ✅ 列表循环也应基于 pr.object_list -->
{% for i in pr.object_list %}
<div class="col-lg-3 ...">
<a href="%7B%7B%20i.get_url%20%7D%7D">{{ i.name }}</a>
...
</div>
{% endfor %}
⚠️ 注意事项:
- 避免变量混淆:如答案中指出,pr、ct 等缩写严重降低可读性。建议改用语义化名称,例如 products_page、categories;
- 异常处理已完备:视图中对 EmptyPage 和 InvalidPage 的捕获是标准实践,无需修改;
- URL 参数安全:当前 ?page={{pg}} 方式适用于简单分页;若页面含其他查询参数(如搜索、筛选),推荐使用 {% url %} + request.GET.urlencode 构建更健壮的分页链接;
- CSS 类名校验:示例中使用了 activate,但 Bootstrap 等框架常用 active,请确认 CSS 类名拼写一致,否则高亮样式可能失效。
总结:Django 分页的核心逻辑在于「对象传递 → 模板绑定 → 属性访问」三步闭环。只要确保模板中所有分页相关属性(如 pr.number、pr.paginator.num_pages、pr.has_next)均基于同一上下文键 pr 调用,分页器即可稳定显示。重构变量命名、补充前后页导航、验证样式类名,即可交付专业、健壮的分页体验。











