关于本站
1、基于Django+Bootstrap开发
2、主要发表本人的技术原创博客
3、本站于 2015-12-01 开始建站
2016年7月5号修改:之前这篇文章写得一塌糊涂,现重新再写一次
我们的文章或者评论什么之类多了之后,如果用一个页面显示就会很长,阅读不方便而且加载速度慢。
这时候,就需要对这些内容进行分页处理。
Django自身已经集成了一个分页器,不要我们重新造轮子,直接使用就行。看看下面简单的示例代码:
from django.core.paginator import Paginator #导入分页器 from blog.models import Blog #自己的模型对象 blogs = Blog.objects.all() #获取全部博文 pages = Paginator(blogs, 10) #每10个博文对象分为1页 #分页器相关的方法和属性 print pages.count #得到里面总共有多少个模型对象 print pages.num_pages #总页数 print pages.page_range #页面列表,可以拿来遍历得到全部页码 #得到第1页包含的模型对象,该对象集合可以用于遍历得到里面的模型对象 blogs_page = pages.page(1) print blogs_page.number #得到该对象集合当前是哪一页 print blogs_page.has_previous() #判断是否有前一页 print blogs_page.has_next() #判断是否有后一页
有了这些方法之后,我们就可以进一步开发这个分页器的功能了。当然,这些我也记不住,都是用dir得到Paginator里面的方法,一个一个分析的。
之前我的博文列表页面的响应方法大致如下(只写出关键部分):
from blog.models import Blog def index(request): """show blogs' list""" data = {} blogs = Blog.objects.all() data["blogs"] = blogs return render_to_response('blog/blog_list.html',data)
加入分页器,修改成如下代码:
from blog.models import Blog from django.core.paginator import Paginator def index(request): """show blogs' list""" data = {} #获取GET请求的参数,得到当前页码。若没有该参数,默认为1 current_page = request.GET.get("page", 1) blogs = Blog.objects.all() pages = Paginator(blogs, 7) #7个对象为1页,这个参数可以写在settings.py里面 blogs = pages.page(current_page) #获得当前页的数据 data["blogs"] = blogs date["pages"] = pages return render_to_response('blog/blog_list.html',data)
修改对应的html模版页面如下:
{# 博文之前的就照常加载,这部分我只是简单写出来,略过,重点是分页部分 #} {% for blog in blogs %} {{blog.caption}} {# 过滤掉HTML标签和处理HTML转义,输出前100个字符 #} {{blog.content|striptags|safe|truncatechars:100}} {% endfor %} {# 分页部分 #} <div> <span class="blog_footer_tip"> 共{{pages.count}}篇博文。当前第{{blogs.number}}页,共{{pages.num_pages}}页 </span> <ul class="pagination"> {# 上一页,这里需要用到has_previous方法判断是否有上一页 #} <li> <a href="?page= {% if blogs.has_previous %} {{blogs.previous_page_number}} {% else %} {{blogs.number}} {% endif %} " aria-label="Previous"> <span aria-hidden="true">«</span> </a> </li> {# 遍历所有页码 #} {% for page in pages.page_range %} <li><a href="?page={{page}}">{{page}}</a></li> {% endfor %} {# 下一页,这里需要用到has_next方法判断是否有下一页 #} <li> <a href="?page= {% if blogs.has_next %} {{blogs.next_page_number}} {% else %} {{blogs.number}} {% endif %} " aria-label="Next"> <span aria-hidden="true">»</span> </a> </li> </ul> </div> {% block extra_footer %} {#设置凸显当前的页码#} <script type="text/javascript"> $(".pagination li:eq({{blogs.number}})").addClass("active"); </script> {% endblock %}
ul标签的pagination类是bootstrap的分页器。具体可以参考:http://v3.bootcss.com/components/#pagination
该分页器分为3部分,上一页按钮,全部页面,下一页按钮。
上一页和下一页的页码可以用previous_page_number和next_page_number得到。
不过使用这两个方法之前需要先用has_previous和has_next方法判断。否则若没有对应页码的话,会报错。
这里还写了一段jquery代码,用于凸显当前的页码,让浏览的人可以一下看到当前是属于哪一页的。
最终效果如下:
(前期的文章不是很多,可以直接罗列全部页码处理。先拿出来使用,后面页码多了再进一步处理)
另外,我的网站不止这个地方需要用到分页器。点击标签筛选博文列表的处理方法也需要用到,而且该分页的代码比较相似。可以把这部分代码封装一下,写成一个通用的函数。
from django.core.paginator import Paginator from django.conf import settings def getPages(request, objectlist): """get the paginator""" currentPage = request.GET.get('page', 1) paginator = Paginator(objectlist, settings.EACHPAGE_NUMBER) objectlist = paginator.page(currentPage) return paginator, objectlist
在settings.py文件加多了一个EACHPAGE_NUMBER参数,用于设置多少个对象分成1页。
当然名字自己命名即可,自定义的,然后就可以在这里引用并使用。
传递request请求和模型对象集合进来,分页处理之后,再传递回去。
由于这个方法比较通用。我在根目录创建了一个文件夹helper,加了__init__.py文件(这样才会把这个文件夹识别为包,可被引用)。
把这个方法单独放到一个py文件中,文件名为paginator.py。原blog列表的方法则改成:
from blog.models import Blog from helper.paginator import getPages #导入helper文件夹的分页通用方法 def index(request): """show blogs' list""" data = {} #获取GET请求的参数,得到当前页码。若没有该参数,默认为1 current_page = request.GET.get("page", 1) blogs = Blog.objects.all() pages, blogs = getPages(request, blogs) #分页处理 data["blogs"] = blogs date["pages"] = pages return render_to_response('blog/blog_list.html',data)
哈哈,这样就简单完成了分页功能。(后面文章多了导致页码变多,可再继续拓展完善:我的网站搭建(第22天) 分页器优化)
ysh
评论测试
2015-12-18 09:36 回复