Django博客网站分页功能失效,附前后端代码寻求解决方案
Django博客分页功能实现修正方案
现有代码问题汇总
blogs_pagination接口存在语法错误:序列化行误写为blogs.serialize(),blogs是分页页对象而非单条博客实例,会直接抛出异常home视图首次加载返回全量博客数据,未携带分页状态,模板渲染时没有初始分页信息- 前端模板只有分页HTML骨架,没有绑定点击事件、请求分页接口、更新页面内容的逻辑
- 分页接口未处理非法页码(如超过最大页、非数字页码),容易触发404或报错
修正步骤
1. 修正后端视图代码
from django.core.paginator import Paginator def home(request): # 首次加载返回第一页分页数据,兼容非JS场景 all_blogs = BlogModel.objects.all().order_by("-created_at") paginator = Paginator(all_blogs, 3) page_number = request.GET.get('page', 1) page_obj = paginator.get_page(page_number) context = { "blogs": page_obj, "services": Service.objects.all(), "works": RecentWork.objects.all(), "has_next": page_obj.has_next(), "has_previous": page_obj.has_previous(), "total_pages": paginator.num_pages, "current_page": page_obj.number } return render(request,"home.html", context) def blogs_pagination(request, page_number=1): blogs_query = BlogModel.objects.all().order_by("-created_at") paginator = Paginator(blogs_query, 3) # get_page自动处理非法页码,自动返回有效页 current_page = paginator.get_page(page_number) return JsonResponse({ # 修正序列化错误,遍历单条博客序列化 "blogs": [blog.serialize() for blog in current_page], "totalPages": paginator.num_pages, "hasNext": current_page.has_next(), "hasPrevious": current_page.has_previous(), "currentPage": current_page.number })
2. 配置分页路由
在你应用的urls.py中新增分页接口路由:
from django.urls import path from . import views urlpatterns = [ path('', views.home, name='home'), path('blogs/page/<int:page_number>/', views.blogs_pagination, name='blogs_pagination'), ]
3. 补全BlogModel序列化方法
确保你的BlogModel模型已经定义了serialize方法,返回前端需要的字段:
from django.db import models class BlogModel(models.Model): title = models.CharField(max_length=200) content = models.TextField() created_at = models.DateTimeField(auto_now_add=True) # 其他字段自行补充 def serialize(self): return { "id": self.id, "title": self.title, "content": self.content, "created_at": self.created_at.strftime("%Y-%m-%d %H:%M:%S") }
4. 修正前端模板代码
如果需要异步无刷新分页,替换你的home.html相关代码如下:
<!-- 博客列表容器 --> <div id="blog-list"> {% for blog in blogs %} <div class="blog-item"> <h3>{{ blog.title }}</h3> <p>{{ blog.content|truncatechars:200 }}</p> <span>发布时间:{{ blog.created_at|date:"Y-m-d H:i" }}</span> </div> {% endfor %} </div> <!-- 分页导航 --> <nav aria-label="Page navigation"> <ul id='pagination' class="pagination justify-content-end container-fluid"> <li id='hasPrevious' class="page-item {% if not has_previous %}disabled{% endif %}"> <a class="page-link" href="javascript:;" aria-label="上一页" data-page="{{ current_page|add:-1 }}"> <span aria-hidden="true">«</span> </a> </li> <!-- 动态渲染页码按钮 --> {% for num in "x"|rjust:total_pages %} <li class="page-item {% if forloop.counter == current_page %}active{% endif %}"> <a class="page-link" href="javascript:;" data-page="{{ forloop.counter }}">{{ forloop.counter }}</a> </li> {% endfor %} <li id='hasNext' class="page-item {% if not has_next %}disabled{% endif %}"> <a class="page-link" href="javascript:;" aria-label="下一页" data-page="{{ current_page|add:1 }}"> <span aria-hidden="true">»</span> </a> </li> </ul> </nav> <!-- 分页交互逻辑 --> <script> let currentPage = {{ current_page }}; // 拼接分页接口基础地址 const basePaginationUrl = "{% url 'blogs_pagination' page_number=0 %}".slice(0, -1); // 绑定所有分页按钮点击事件 document.querySelectorAll(".page-link").forEach(link => { link.addEventListener("click", function(e) { e.preventDefault(); const targetPage = parseInt(this.dataset.page); if (targetPage < 1 || targetPage > {{ total_pages }}) return; // 请求分页数据 fetch(`${basePaginationUrl}${targetPage}/`) .then(res => res.json()) .then(data => { // 替换博客列表内容 const blogList = document.getElementById("blog-list"); blogList.innerHTML = ""; data.blogs.forEach(blog => { const item = document.createElement("div"); item.className = "blog-item"; item.innerHTML = ` <h3>${blog.title}</h3> <p>${blog.content.substring(0, 200)}</p> <span>发布时间:${blog.created_at}</span> `; blogList.appendChild(item); }); // 更新分页按钮状态 document.getElementById("hasPrevious").classList.toggle("disabled", !data.hasPrevious); document.getElementById("hasNext").classList.toggle("disabled", !data.hasNext); // 更新页码激活状态 document.querySelectorAll(".page-item").forEach(item => { const page = parseInt(item.querySelector(".page-link")?.dataset.page); if (page) item.classList.toggle("active", page === data.currentPage); }); // 更新上下页按钮的目标页码 document.querySelector("#hasPrevious .page-link").dataset.page = data.currentPage - 1; document.querySelector("#hasNext .page-link").dataset.page = data.currentPage + 1; currentPage = data.currentPage; }); }); }); </script>
如果你不需要异步刷新,也可以用更简单的服务端渲染方案,不用写任何JS,只需要把分页按钮的href改为/?page=目标页码即可。
内容的提问来源于stack exchange,提问作者daya
相关产品推荐
相关产品推荐

