一、为什么先讲分页功能
1.新增或编辑博客内容。
2.博客文章数较多--> 全部加载过慢-->分页加载。
3.增加讲解的基础

二、快速添加博客

1.dos模式下打开虚拟环境,加入mysite002项目,输入Python manage.py shell进入shell模式。
2.from myblog.mdels import Blog
3.模型新增对象

引入用到的模型 from myblog.models import Blog,BlogType
引入用户 from django.contrib.auth.models import User
查看内容 Blog.objects.all() BlogType.objects.all() User.objects.all()
查看数量 Blog.object.count() 或Blog.objects.all().count()
新建博客
blog=Blog() #实例化对象
blog.title="第四篇博客"
blog.blog_type=BlogType.objects.all()[0]
blog.content="shell模式下的第一篇博客"
blog.author=User.objects.all()[0]
blog.save()
shell模式下用for循环批量添加博客 其中blog_type、user提前给予一个值。
for i in rang(1,31):
blog=Blog()
blog.title="for %s" % i
blog.content="xxxx: %s" % i
blog.blog_type=blog_type
blog.author=user
blog.save()
四、分页
1.引入分页器 from django.core(核心).paginator(分页器) import Paginator(类)
2.查看当前环境下打开的 文件 dir(), 关闭无用的文件 del。
3.分页器实现分页

修改模型,在models中添加排序。 退出shell,迁移刷新数据库。
class Meta:
ordering=['-created_time']
4. 引入分页器等,进行分页
from django.core.paginator import Paginator from myblog.models import Blog blogs=Blog.object.all() paginator=Paginator(blogs,10)
dir(paginator)可以查看paginator属性及方法。
五、分页器使用

1.修改views.py方法。
1 def blog_list(request): # 2 blogs_all_list=Blog.objects.all() #获取Blog全部数据 3 paginator=Paginator(blogs_all_list,10) #每10篇分页 4 page_num=request.GET.get('page',1) # 从request中获取分页参数。及get请求。 5 page_of_blogs=paginator.get_page(page_num) #用get_page方法可以不用转换page_num的整数或字符类型。 6 7 context={} 8 9 context['page_of_blogs']=page_of_blogs 10 context['blog_types']=BlogType.objects.all() 11 context['blogs_count']=Blog.objects.all().count() 12 return render_to_response('myblog/blog_list.html',context)
分页器独立出来,代码如下: 在blog_list中运行函数paginator传出字典context。
1 def paginator(request,all_list): 2 paginator = Paginator(all_list,settings.EACH_PAGE_NUMBER) #分页 settings.EACH_PAGE_NUMBER从settings中引入自定义的每页数量。 3 page_num = request.GET.get('page',1) #获取url的页面参数(GET请求) 4 page = paginator.get_page(page_num) #get_page自动识别并处理 数值型或非数值型页码,当前页 5 page_list=page.object_list #当前页内容列表 6 currentr_page_num = page.number #获取当前页码 7 page_range = list(range(max(currentr_page_num-2,1),currentr_page_num))+\ 8 list(range(currentr_page_num,min(currentr_page_num+2,paginator.num_pages)+1)) 9 # 加上省略号 10 if page_range[0]-1 >= 2: 11 page_range.insert(0,'...') 12 if paginator.num_pages - page_range[-1] >= 2: 13 page_range.append('...') 14 15 #显示第1页和最后一页 16 if page_range[0] != 1: 17 page_range.insert(0,1) 18 if page_range[-1] != paginator.num_pages: 19 page_range.append(paginator.num_pages) 20 # 传出参数 21 context={} 22 context['page'] = page # 传出当前页码 23 context['page_list'] = page_list #当前页内容 24 context['page_range'] = page_range #传出要显示的页码 25 return context 26 27 def blog_list(request): 28 all_list=Blog.objects.all() 29 context = paginator(request,all_list) 30 31 context['blogs'] = Blog.objects.all() 32 context['blogs_count'] = Blog.objects.all().count() 33 blog_types = BlogType.objects.all() 34 context['blog_types'] = blog_types 35 return render_to_response('blog_list.html',context)
2.修改网页模版。把blogs改为page_of_bigs。
{% for blog in page_of_blogs.object_list %}
3.添加分页页码。在bootstrap组件、分页中复制代码进行修改。
<div>
<ul class="pagination">
<li> {#上一页#}
{% if page_of_blogs.has_previous %}
<a href="?page={{page_of_blogs.previous_page_number}}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
{% else %}
<span aria-hidden="true">«</span>
<% endif %}
</li> {# 全部页面 #}
{% for page_num in page_of_blogs.paginator.page_range %}
<li><a href="?page={{page_num}}">{{ page_num }}</a></li>
{% endfor %}
<li> {#下一页#}
{% if page_of_blogs.has_next %}
<a href="?page={{page_of_blogs.next_page_number}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
{% else %}
<span aria-hidden="true">»</span>
{% endif %}
</li>
</ul>
</div>
六、继续优化。
1.分页器优化,在方法中增加一条context['blogs']=page_of_blogs.object_list, 更换网页中{% for blog in page_of_blogs.object_list %}为{% for blog in blogs %}
2.继续优化页码。a 当前页高亮。 b 页码显示不要太多,以免影响布局。
3.当前页高亮显示,先判断是否为当前页,是就高亮显示,增加class=‘active’。由于当前页不需要链接所以a标签改为span标签,去掉链接。
1 {% for page_num in page_of_blogs.paginator.page_range %} 2 {% if page_num == page_of_blogs.number %} 3 <li class='active'><span>{{ page_num }}</span></li> 4 {% else %} 5 <li ><a href="?page={{page_num}}">{{ page_num }}</a></li> 6 {% endif %} 7 {% endfor %}
4.缩短页码显示,显示当前页前后各3页,在views中修改。
1 def blog_list(request): # 2 blogs_all_list=Blog.objects.all() 3 paginator=Paginator(blogs_all_list,2) #每n篇分为一页。 4 page_num=request.GET.get('page',1) #从request中取得当前页码,默认第一页。 5 page_of_blogs=paginator.get_page(page_num) #当前页内容 6 7 currentr_page_num=page_of_blogs.number #取得当前页,做一个前后各3页的列表。 8 page_range=[currentr_page_num-3, currentr_page_num-2, currentr_page_num-1, currentr_page_num,currentr_page_num+1, currentr_page_nu +2 currentr_page_num+3 ] 9 10 context={} 11 context['blogs']=page_of_blogs.object_list 12 context['page_of_blogs']=page_of_blogs 13 14 context['page_range']=page_range #显示页码传给一个参数 15 16 context['blog_types']=BlogType.objects.all() 17 context['blogs_count']=Blog.objects.all().count() 18 return render_to_response('myblog/blog_list.html',context) 19
修改页面 {% for page_num in page_range %}
继续修改页码显示,1页之前和最后一页之后不在有页码。继续修改views。
currentr_page_num=page_of_blogs.number page_range=list(range(max(currentr_page_num-3,1),currentr_page_num))+list(range(currentr_page_num,min(paginator.num_pagesviews,currentr_page_num+3)+1)) print(page_range)
其中print(page_range)可以用来在shell中调试页码。
增加第一页和最后一页,判断并增加省略号。
1 def blog_list(request): # 2 blogs_all_list=Blog.objects.all() 3 paginator=Paginator(blogs_all_list,2) # 4 page_num=request.GET.get('page',1) 5 page_of_blogs=paginator.get_page(page_num) 6 7 currentr_page_num=page_of_blogs.number 8 page_range=list(range(max(currentr_page_num-3,1),currentr_page_num))+list(range(currentr_page_num,min(paginator.num_pages,currentr_page_num+3)+1)) 9 10 if page_range[0]-1 >=2: 11 page_range.insert(0,'...') 12 if paginator.num_pages - page_range[-1] >=3: 13 page_range.append('...') 14 15 if page_range[0]!=1: 16 page_range.insert(0,1) 17 if page_range[-1]!=paginator.num_pages: 18 page_range.append(paginator.num_pages) 19 20 context={} 21 context['blogs']=page_of_blogs.object_list 22 context['page_of_blogs']=page_of_blogs 23 24 context['page_range']=page_range 25 26 context['blog_types']=BlogType.objects.all() 27 context['blogs_count']=Blog.objects.all().count() 28 return render_to_response('myblog/blog_list.html',context) 29
修改模版页面,取消省略号链接。
1 {% for page_num in page_range %} 2 {% if page_num == page_of_blogs.number %} 3 <li class='active'><span>{{ page_num }}</span></li> 4 {% else %} 5 {% if page_num == '...' %} 6 <li><span>{{ page_num }}</spam></li> 7 {% else %} 8 <li ><a href="?page={{page_num}}">{{ page_num }}</a></li> 9 {% endif %} 10 {% endif %} 11 {% endfor %}
将博客统计数移到末尾ul标签之后。
</ul>
<p>
共有{{ blogs_count }}篇博客,
当前第{{page_of_blogs.number}}页,共{{page_of_blogs.paginator.num_pages}}页。
</p>
将页码部分居中。在div标签中设置class属性,并在css设置。
1 <div class="paginator"> 2 <ul class="pagination">
div.paginator{ text-align:center; }
分页中每几篇 文章分为一页,可以在views中设置一个公共变量each_page_blogs_number=5,然后在方法内传入变量。另一种方法是settings自定义设置。
七、settings自定义设置

在settings末尾写入,然后在views中引入。
#自定义参数
EACH_PAGE_BLOGS_NUMBER = 5
from django.conf import settings
修改分页博客数为: settings.EACH_PAGE_BLOGS_NUMBER
浙公网安备 33010602011771号