django基础(四)- 分页组件

一、django内置分页

django内置分页使用到两个类:Paginator,Page 

主要有如下方法及参数:

#paginator对象
paginator = Paginator(L, 10)

# per_page: 每页显示条目数量
# count:    数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page:     page对象

#page对象
posts = paginator.page(current_page)
# has_next              是否有下一页
# next_page_number      下一页页码
# has_previous          是否有上一页
# previous_page_number  上一页页码
# object_list           分页之后的数据列表
# number                当前页
# paginator             paginator对象

--------------------------------------------------------------------------------------------------------

可以CustomPaginator(Paginator),创建自己独特的方法

需要传入的数据:

  1. 所有数据
  2. 当前页
  3. 每页显示的条目数
  4. 最多页面个数

view.py文件内容

from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger

USER_LIST = []
for i in range(1,300):
    temp = {'name':'root'+str(i),'age':i}
    USER_LIST.append(temp)

# def index(request):
#     per_page_count = 10
#     current_page = int(request.GET.get('p'))
#
#     start = (current_page-1)*per_page_count
#     end = current_page * per_page_count
#     data = USER_LIST[start:end]
#
#     prev_pager = current_page - 1
#     next_pager = current_page + 1
#     return render(request,'index.html',{'user_list':data,'prev_pager':prev_pager,'next_pager':next_pager})

# def index1(request):
#     current_page = request.GET.get('p')   #获取当前的页码
#     paginator = Paginator(USER_LIST,10)   #Paginator实例化对象
#
#     try:
#         posts = paginator.page(current_page)  #当前页面实例化page对象
#     except PageNotAnInteger:                  #如果输入的不是整数
#         posts = paginator.page(1)             #第一页
#     except EmptyPage:                         #后面没有页码了
#         posts = paginator.page(paginator.num_pages)  #最后一页
#     return render(request,'index1.html',{'posts': posts})


class CustomPaginator(Paginator):  #继承,自定义方法
    def __init__(self,current_page,per_pager_num,*args,**kwargs):
        super(CustomPaginator,self).__init__(*args,**kwargs)
        #当前页
        self.current_page=int(current_page)
        #最多显示的页码数量
        self.per_pager_num=int(per_pager_num)

    def pager_num_range(self):
        #当前页:self.current_page
        #最多显示的页码数量:self.per_pager_num
        #总页数:self.num_pages
        if self.num_pages < self.per_pager_num:
            return range(1,self.num_pages+1)
        #当总页数很多时
        part = int(self.per_pager_num/2)
        if self.current_page <= part:
            return range(1,self.per_pager_num+1)
        if (self.current_page + part) > self.num_pages:
            return range(self.num_pages-self.per_pager_num+1,self.num_pages)

        return range(self.current_page-part,self.current_page+part+1)


def index1(request):
    current_page = request.GET.get('p')
    paginator = CustomPaginator(current_page,11,USER_LIST,10)
    try:
        posts = paginator.page(current_page)
    except PageNotAnInteger:
        posts = paginator.page(1)  #第一页
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)  #最后一页
    return render(request,'index1.html',{'posts': posts})

index1.html文件内容

image

#index1.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
    <ul>
        {% for row in posts.object_list %}
            <li>{{ row.name }}-{{ row.age }}</li>
        {% endfor %}
    </ul>
    {% include 'include/pager.html' %}

</body>
</html>
#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

#pager.html

{% if posts.has_previous %}
    <a href="/index1.html?p={{ posts.previous_page_number }}">上一页</a>
{% else %}
    <a href="#">上一页</a>
{% endif %}

{% for i in posts.paginator.pager_num_range %}
    {% if i == posts.number %}
        <a style="color: red" href="/index1.html?p={{ i }}">{{ i }}</a>
    {% else %}
        <a href="/index1.html?p={{ i }}">{{ i }}</a>
    {% endif %}
{% endfor %}

{% if posts.has_next %}
    <a href="/index1.html?p={{ posts.next_page_number }}">下一页</a>
{% else %}
    <a href="#">下一页</a>
{% endif %}
<span>
        {{ posts.number }}/{{ posts.paginator.num_pages }}
</span>

效果:

image

二、自定义分页

不使用django内置组件,自己单独创建类

需要传入的数据:

  1. 所有数据的个数
  2. 当前页
  3. 每页显示条目数
  4. 最多页面个数

pager.py文件

class Pagination(object):
    def __init__(self,totalCount,currentPage,perPageItemNum=20,maxPageNum=7):
        #数据总个数
        self.total_count = totalCount
        #当前页
        try:
            v = int(currentPage)
            if v <=0:
                v=1
            self.current_page = v
        except Exception as e:
            self.current_page = 1
        #每页显示的条数
        self.per_page_item_num = perPageItemNum
        #最多显示的页码
        self.max_page_num = maxPageNum

    def start(self):
        return (self.current_page - 1) * self.per_page_item_num

    def end(self):
        return self.current_page * self.per_page_item_num

    @property   #静态方法
    def num_pages(self):
        #总页数
        a,b=divmod(self.total_count,self.per_page_item_num)  #divmod(10,3)  ==>(3, 1)
        if b==0:
            return a
        return a+1

    def pager_num_range(self):
        #当前页:self.current_page
        #最多显示的页码数量:self.per_pager_num
        #总页数:self.num_pages
        if self.num_pages < self.max_page_num:
            return range(1,self.num_pages+1)
        #当总页数很多时
        part = int(self.max_page_num/2)
        if self.current_page <= part:
            return range(1,self.max_page_num+1)
        if (self.current_page + part) > self.num_pages:
            return range(self.num_pages-self.max_page_num+1,self.num_pages)

        return range(self.current_page-part,self.current_page+part+1)

    def page_str(self):
        page_list=[]
                
                #首页
        first = "<li><a href='/index2.html?p=1'>首页</a></li>"
        page_list.append(first)

                #上一页
        if self.current_page == 1:
            prev="<li><a href='#'>上一页</a></li>"
        else:
            prev="<li><a href='/index2.html?p=%s'>上一页</a></li>" %(self.current_page-1)
        page_list.append(prev)

        for i in self.pager_num_range():
            if i == self.current_page:
                temp = "<li class='active'><a class='active' href='/index2.html?p=%s'>%s</a></li>" %(i,i)
            else:
                temp = "<li><a href='/index2.html?p=%s'>%s</a></li>" % (i,i)
            page_list.append(temp)

        if self.current_page == self.num_pages:
            nex = "<li><a href='#'>下一页</a></li>"
        else:
            nex = "<li><a href='/index2.html?p=%s'>下一页</a></li>" %(self.current_page+1)
        page_list.append(nex)

        last = "<li><a href='/index2.html?p=%s'>尾页</a></li>" %self.num_pages
        page_list.append(last)

        return ' '.join(page_list)

image

html文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css"/>
</head>
<body>
<ul>
    {% for row in data %}
        <li>{{ row.name }}-{{ row.age }}</li>
    {% endfor %}

{#    {% for i in page_obj.pager_num_range %}#}
{#        <a href="/index2.html?p={{ i }}">{{ i }}</a>#}
{#    {% endfor %}#}
{#    <hr/>#}

</ul>
<ul class="pagination">

    {{ page_obj.page_str|safe }}
</ul>

</body>
</html>

view.py文件

def index2(request):
    from app01.pager import Pagination
    current_page = request.GET.get('p')
    page_obj = Pagination(300,current_page)
    data_list = USER_LIST[page_obj.start():page_obj.end()]

    return render(request,'index2.html',{'data':data_list,'page_obj':page_obj})

效果:

image

参考文档:https://www.cnblogs.com/wupeiqi/articles/5246483.html

原文地址:https://www.cnblogs.com/hujinzhong/p/11598694.html