14 优化分页展示
技术交流QQ群:1027579432,欢迎你的加入!
本教程来源于B站杨仕航Django2.0开发视频教程,如需转载,必须注明来源!
1.优化分页展示
- 上一讲中的分页展示存在的问题如下:
- 无法知道当前是在哪一页,如下图所示。
-
如果每2篇文章当作一页,就会使得分页展示很长。
分页展示存在的问题.png
友好的分页展示.png
- 修改blog文件目录下的templates模板文件夹下的blog_list.html文件,在代码{% for page_num in page_of_blogs.paginator.page_range %}下方添加如下代码,从而使当前页高亮显示:
{% if page_num == page_of_blogs.number %} <li class="active"> <span>{{ page_num }}</span> </li> {% else %} <li> <a href="?page={{ page_num }}">{{ page_num }}</a> </li> {% endif %}
- 仅显示当前页前后两页的页码,不显示所有的页码。因此对blog_list.html文件进行修改,因为代码{% for page_num in page_of_blogs.paginator.page_range %}是对所有博客都进行了遍历,所以要修改blog文件目录下的views.py文件,在blog_list()函数中添加仅显示当前页前后两页的页码的代码,如下所示:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from .models import Blog, BlogType # Create your views here. def blog_list(request): blogs_all_list = Blog.objects.all() paginator = Paginator(blogs_all_list, 2) # 每2篇进行一次分页 page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 page_range = [current_page_num - 2, current_page_num - 1, current_page_num, current_page_num + 1, current_page_num + 2, ] context = {} context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blog_list.html', context) def blog_detail(request, blog_pk): context = {} context['blog'] = get_object_or_404(Blog, pk=blog_pk) return render_to_response('blog/blog_detail.html', context)
- 接着修改blog_list.html文件中的{% for page_num in page_of_blogs.paginator.page_range %}为{% for page_num in page_range %}
- 当点击第1页或第17页时,就会出现如下的错误。因此修改blog文件目录下的views.py文件中的blog_list()函数。如下所示:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from .models import Blog, BlogType # Create your views here. def blog_list(request): blogs_all_list = Blog.objects.all() paginator = Paginator(blogs_all_list, 2) # 每2篇进行一次分页 page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) context = {} context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blog_list.html', context) def blog_detail(request, blog_pk): context = {} context['blog'] = get_object_or_404(Blog, pk=blog_pk) return render_to_response('blog/blog_detail.html', context)
错误.png
正确.png
- 当点击中间某一页时,需要将第一页和最后一页的页码也显示出来。因此,继续修改blog文件目录下的views.py文件中的blog_list()函数。如下所示:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from .models import Blog, BlogType # Create your views here. def blog_list(request): blogs_all_list = Blog.objects.all() paginator = Paginator(blogs_all_list, 2) # 每2篇进行一次分页 page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blog_list.html', context) def blog_detail(request, blog_pk): context = {} context['blog'] = get_object_or_404(Blog, pk=blog_pk) return render_to_response('blog/blog_detail.html', context)
当点击中间某一页时,需要将第一页和最后一页的页码也显示出来.png
- 通过上图我们可以发现,第7页与最后一页之间相差太多。它们之间可以用省略号表示两者之间相差很多页。因此,继续修改blog文件目录下的views.py文件中的blog_list()函数。如下所示:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from .models import Blog, BlogType # Create your views here. def blog_list(request): blogs_all_list = Blog.objects.all() paginator = Paginator(blogs_all_list, 2) # 每2篇进行一次分页 page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) # 加上省略页码标记 if page_range[0] - 1 >= 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # 加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blog_list.html', context) def blog_detail(request, blog_pk): context = {} context['blog'] = get_object_or_404(Blog, pk=blog_pk) return render_to_response('blog/blog_detail.html', context)
正确显示.png
- 当点击上图中的省略号时,会出现下图中的情况。因此,需要对blog文件目录下的blog_list.html模板文件进行修改,即对全部页码部分进行修改,如下所示:
{# 全部页码 #} {% for page_num in page_range %} {% if page_num == page_of_blogs.number %} <li class="active"> <span>{{ page_num }}</span> </li> {% else %} {% if page_num == '...' %} <li> <span>{{ page_num }}</span> </li> {% else %} <li> <a href="?page={{ page_num }}">{{ page_num }}</a> </li> {% endif %} {% endif %} {% endfor %}
点击省略号时,不应该发送请求.png
- 博客总数量在前端页面中的展示位置需要重新布局,因此对blog文件目录下的blog_list.html模板文件进行修改,即对(一共有34篇博客)进行修改,给div盒子增加一个类名为paginator,同时增加一个p标签,当中放入共有{{ page_of_blogs.paginator.count }}篇博客,当前第{{ page_of_blogs.number }}页,共{{ page_of_blogs.paginator.num_pages }}页,如下所示:
{% extends 'base.html' %} {# blog_list.html文件内容 #} {# 页面标题 #} {% block title %}我的网站{% endblock %} {% block nav_blog_active %}active{% endblock %} {% load staticfiles %} {% block header_extends %} <link rel="stylesheet" href="{% static 'blog/blog.css' %}"> {% endblock %} {# 页面内容 #} {% block content %} <div class="container"> <div class="row"> <div class="col-xs-12 col-sm-8 col-md-9 col-lg-10"> <div class="panel panel-default"> <div class="panel-heading"> {% block blog_list_title %}博客列表{% endblock %} </div> <div class="panel-body"> <!-- 下一行中的blogs来自于views.py中的context['blogs'] = Blog.objects.all() --> {% for blog in blogs %} <div class="blog"> <!-- 下一行中的blog.title来自于models.py中的title = models.CharField(max_length=50) --> <h3><a href="{% url 'blog_detail' blog.pk %}">{{ blog.title }}</a></h3> <p class="blog-info"> <span class="glyphicon glyphicon-tag"></span><a href="{% url 'blogs_with_type' blog.blog_type.pk %}">{{ blog.blog_type }}</a>     <span class="glyphicon glyphicon-time"></span>{{ blog.created_time|date:"Y-m-d" }} </p> <p>{{ blog.content|truncatechars:120 }}</p> </div> {% empty %} <div class="bog"> <h3>暂无博客,敬请期待</h3> </div> {% endfor %} </div> </div> <!-- 此处使用了bootstrp组件中的分页代码 --> <div class="paginator"> <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_range %} {% if page_num == page_of_blogs.number %} <li class="active"> <span>{{ page_num }}</span> </li> {% else %} {% if page_num == '...' %} <li> <span>{{ page_num }}</span> </li> {% else %} <li> <a href="?page={{ page_num }}">{{ page_num }}</a> </li> {% endif %} {% endif %} {% 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> <p>共有{{ page_of_blogs.paginator.count }}篇博客,当前第{{ page_of_blogs.number }}页,共{{ page_of_blogs.paginator.num_pages }}页</p> </div> </div> <div class="hidden-xs col-sm-4 col-md-3 col-lg-2"> <div class="panel panel-default"> <div class="panel-heading"> 博客分类 </div> <div class="panel-body"> <ul class="blog-types"> {% for blog_type in blog_types %} <li><a href="{% url 'blogs_with_type' blog_type.pk %}">{{ blog_type.type_name }}</a></li> {% empty %} <li>暂无分类</li> {% endfor %} </ul> </div> </div> </div> </div> </div> {% endblock %}
- 接着,对类名为paginator的div盒子进行css美化,打开blog文件目录下的static/blog文件夹中的blog.css,当中添加如下内容:
div.paginator { text-align: center; }
美化后的页面.png
- 然后,对blog文件目录下views.py文件中的blogs_with_type()函数进行修改,修改后的函数内容如下所示:
def blogs_with_type(request, blog_type_pk): blog_type = get_object_or_404(BlogType, pk=blog_type_pk) blogs_all_list = Blog.objects.filter(blog_type=blog_type) paginator = Paginator(blogs_all_list, 2) # 每2篇进行一次分页 page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) # 加上省略页码标记 if page_range[0] - 1 >= 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # 加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['blog_type'] = blog_type context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blogs_with_type.html', context)
2.settings自定义设置
settings自定义设置.png
- 修改每页所展示的博客数量,首先在全局设置文件settings.py末尾处增加如下内容。
# 自定义参数 EACH_PAGE_BLOGS_NUMBER = 7
- 然后,修改blog文件目录下views.py文件中的和blog_list()和blogs_with_type()函数进行修改,修改后的函数内容如下所示:
from django.shortcuts import render_to_response, get_object_or_404 from django.core.paginator import Paginator from django.conf import settings from .models import Blog, BlogType # Create your views here. def blog_list(request): blogs_all_list = Blog.objects.all() paginator = Paginator( blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) # 加上省略页码标记 if page_range[0] - 1 >= 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # 加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blog_list.html', context) def blog_detail(request, blog_pk): context = {} context['blog'] = get_object_or_404(Blog, pk=blog_pk) return render_to_response('blog/blog_detail.html', context) def blogs_with_type(request, blog_type_pk): blog_type = get_object_or_404(BlogType, pk=blog_type_pk) blogs_all_list = Blog.objects.filter(blog_type=blog_type) paginator = Paginator(blogs_all_list, settings.EACH_PAGE_BLOGS_NUMBER) page_num = request.GET.get('page', 1) # 获取url的页码参数(GET请求) page_of_blogs = paginator.get_page(page_num) current_page_num = page_of_blogs.number # 获取当前页码 # 获取当前页码前后各两页的页码范围 page_range = list(range(max(current_page_num - 2, 1), current_page_num)) + \ list(range(current_page_num, min( current_page_num + 2, paginator.num_pages) + 1)) # 加上省略页码标记 if page_range[0] - 1 >= 2: page_range.insert(0, '...') if paginator.num_pages - page_range[-1] >= 2: page_range.append('...') # 加上首页和尾页 if page_range[0] != 1: page_range.insert(0, 1) if page_range[-1] != paginator.num_pages: page_range.append(paginator.num_pages) context = {} context['blog_type'] = blog_type context['blogs'] = page_of_blogs.object_list context['page_of_blogs'] = page_of_blogs context['page_range'] = page_range context['blog_types'] = BlogType.objects.all() return render_to_response('blog/blogs_with_type.html', context)
- 最后,点击具体的某一种博客分类,将例如分类:Django旁边的统计博客数量的显示信息去掉。打开blog文件夹目录下的templates/blogs_with_type.html文件,修改其内容后的结果如下所示:
删除统计博客数量的显示信息.png{% extends 'blog/blog_list.html' %} {# blogs_with_type.html文件内容 #} {# 页面标题 #} {% block title %} {{ blog_type.type_name }} {% endblock %} {% block blog_list_title %} 分类:{{ blog_type.type_name }} <a href="{% url 'blogs_with_type' blog_type.pk %}">查看全部博客</a> {% endblock %}
修改后的结果.png