分页功能实现

Django本身提供简单的分类功能,但不够漂亮,要如何将分页功能实现得漂亮一点呢。这里用的bottstrap进行快速样式处理。

 

这里主要是考虑当页数太多时,需要将一部分页码隐藏起来,但如果页码较少,隐藏是完全没必要的,所以我们以页码大于7为界。

1.总页码少于7,全部显示

2.总页码大于7:

      如:1 2 3 4 5 6 7 8 

      2.1 当前页码大于等于7(当前页码-5大于1),前面页码都有隐藏,左侧显示4,5,6(当,当前为6时因为只有2一个页码,无需省略)

           此时取页码为:page_range[current_page - 4:current_page - 1]

      2.2 此时判断右侧页码,当前页码+5 小于最后一个页码,需要隐藏,否则没必要。

             此时取页码为:page_range[current_page - 1:current_page + 2] + [last_page_num,]

      2.3 其它情况下直接从当前页码取到第一页或者最后一页。

下面看代码:paginate_tags.py

#!usr/bin/env python
# *- coding:utf-8 -*-
# Andy Create @ 7/20/2019 9:48 AM
from django import template
from django.core.paginator import Paginator, PageNotAnInteger, EmptyPage

register = template.Library()


@register.simple_tag(takes_context=True)
def paginate(context, object_list, page_count):
    # page_count ·每页显示的文章数量
    # left_dot 左边是否显示省略号 right_dot same
    # page_num 当前请求的页码 == current_page
    # object_page_list 当前请求页的对象
    #
    paginator = Paginator(object_list, page_count)
    page_num = context['request'].GET.get('page', 1)
    try:
        page_num = page_num
    except PageNotAnInteger:
        page_num = 1
    except EmptyPage:
        page_num = paginator.num_pages

    def get_pages(paginator, page_num, left_dot=False, right_dot=False):
        current_page = int(page_num)
        context['current_page'] = current_page

        page_range = list(paginator.page_range)
        first_page_num = page_range[0]
        last_page_num = page_range[-1]

        if page_range[-1] <= 7:
            pages = list(page_range)
        else:
            # 获取当前页面右侧页码
            if current_page + 5 < last_page_num:
                right_dot = True
                right_pages = page_range[current_page - 1:current_page + 2] + [last_page_num, ]  # include current page
            else:
                right_pages = page_range[current_page - 1:]  # include current page
            # 获取当前页面左侧页码
            if current_page - 5 > first_page_num:
                left_dot = True
                left_pages = [first_page_num, ] + page_range[current_page - 4:current_page - 1]
            else:
                left_pages = page_range[:current_page - 1]
            pages = left_pages + right_pages
        pages = pages[1:-1]
        return pages, right_dot, left_dot

    context['current_page'] = page_num
    pages, right_dot, left_dot = get_pages(paginator, page_num)
    object_page_list = paginator.page(page_num)
    context['article_list'] = object_page_list
    context['pages'] = pages
    context['last_page'] = paginator.num_pages
    context['first_page'] = 1
    context['left_dot'] = left_dot
    context['right_dot'] = right_dot

      最终显示效果为:

上面的样式是用的bootstrap.

html代码如下:

<nav aria-label="...">
    <ul class="pagination">
        {% if article_list.has_previous %}
            <li><a class="previous-page" href="?page={{ article_list.previous_page_number }}">
                上一页
            </a></li>
        {% endif %}
        {% if first_page == current_page %}
            <li class="active"><a href="?page=1">1</a></li>
        {% else %}
            <li><a href="?page=1" class="first-page">1</a></li>
        {% endif %}

        {% if left_dot %}
            <li><span>...</span></li>
        {% endif %}
        {% for page in pages %}
            {% if page == current_page %}
                <li class="active"><span class="current">{{ page }}</span></li>
            {% else %}
                <li><a href="?page={{ page }}">{{ page }}</a></li>
            {% endif %}
        {% endfor %}
        {% if right_dot %}
            <li><span>...</span></li>
        {% endif %}
        {% if last_page != 1 %}
            {% if last_page == current_page %}
                <li class="active"><span>{{ last_page }}</span></li>
            {% else %}
                <li><a href="?page={{ last_page }}">{{ last_page }}</a></li>
            {% endif %}
        {% endif %}
        {% if article_list.has_next %}
            <li><a class="next-page" href="?page={{ article_list.next_page_number }}">下一页</a></li>
        {% endif %}
    </ul>
</nav>

在主页面引入这个标签:(后面的数字7表示每页显示7条博客,可以通过view函数 中的context传入。

{% paginate article_list 7 %}

在博客内容后面引入 这个页码:

<div class="text-center">
    {% include 'pages.html' %}
</div>

 

上一篇:Django media配置的套路

下一篇:Django simple tag不生效 与模板继承