技术交流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> &nbsp&nbsp&nbsp
                                        <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">&laquo;</span>
                                    </a>
                                {% else %}
                                    <span aria-hidden="true">&laquo;</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">&raquo;</span>
                                    </a>
                                {% else %}
                                    <span aria-hidden="true">&raquo;</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