django组件之分页器

在一般情况下,我们的展示的一个页面,都会有分页这个逻辑,我们通过分页的形式,让页面实现跳转,每一个人新的页面都是一个新的请求,每次拿到的都是一个刷新后的页面

如果要实现分页功能的话,可以通过两种方式去实现,一个是django自带了一个分页的模块.

 from django.core.paginator import Paginator


# book_list=Book.objects.all()
    # paginator=Paginator(book_list,10) #调Paginator方法,里面传书籍对象以及你需要分的页数
    # order_num=int(request.GET.get('page',1)) #获得前端页面发送请求的页面信息
    # page=paginator.get_page(order_num) 
    # if paginator.num_pages>11:
    #     if order_num-5<1:
    #         page_range=range(1,11)
    #     elif order_num+5>paginator.num_pages:
    #         page_range=range(paginator.num_pages-10,paginator.num_pages+1)
    #     else:
    #         page_range=range(order_num-5,order_num+6)
    # else:
    #     page_range=paginator.page_range
    # return render(request,'index.html',locals())

前端页面进行渲染

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
    #书籍对象的内容,循环page获取每一条内容的对象 <ul> {% for book in page %} <li>{{ book.title }}----------{{ book.price }}</li> {% endfor %} </ul>

#分页符号的代码逻辑,定义ul里面所有的的内容都是在一行里面 <nav aria-label="Page navigation"> <ul class="pagination"> <li><a href="?page=1" aria-label="Previous"><span>首页</span></a></li> {% if page.has_previous %} <li><a href="?page={{ page.previous_page_number }}" aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% else %} <li class="disabled"><a aria-label="Previous"><span aria-hidden="true">上一页</span></a></li> {% endif %}
  #for循环出来所有的a便签,每次过去都是一次新的页面请求,显示相应的页面信息 {
% for num in page_range %} {% if num == order_num %} <li class="active"><a href="?page{{ num }}">{{ num }}</a></li> {% else %} <li><a href="?page={{ num }}">{{ num }}</a></li> {% endif %} {% endfor %} <li><a href="?page={{ paginator.num_pages }}" aria-label="Previous"><span>尾页</span></a></li> {% if page.has_next %} <li><a href="?page={{ page.next_page_number }}" aria-label="Previous"><span aria-hidden="true">下一页</span></a></li> {% else %} <li class="disabled"><a aria-label="Previous"><span aria-hidden="true">下一页</span></a></li> {% endif %} </ul> </nav> </body> </html>

上面是基于模块实现的分页功能,如果单纯从分页效果来过得话是基本已经实现的,为了更加了解这个模块,仿照它实现方式再自定义一个插件出来,让它更具有拓展性

views函数中代码

from app.page import Pagination

    book_list = Book.objects.all()
    current_page=request.GET.get("page") #获取到一个数字,要显示的那个页面
    pagination=Pagination(current_page,book_list.count(),per_page=10) #传当前访问页面序号,以及这个models对象的数量,以及每个页面要展示的数量
    book_list=book_list[pagination.start:pagination.end] #需要显示的信息就是切片出来的信息,
    return render(request,"index.html",locals())
class Pagination(object):
    def __init__(self,current_page,all_count,per_page=10,max_pager_num=11): #里面定义了4个参数,
        try:
            current_page=int(current_page)    #把需要进入的页面,强转换成int类型的格式,然后判断它的特殊情况,如果小于1或者强转换报错的情况下,都让它等于1
        except Exception as e:   
            current_page=1
        if current_page<1:
            current_page=1
        self.current_page=current_page
        self.all_count=all_count
        self.per_page=per_page

        # 计算总共页数,总数据的条数/每个页面需要展示的数量
        num_pages,tmp=divmod(all_count,per_page)   #计算总共页数,调用divmod方法,前面一个数被除数后面一个是除数,如果它有余数的话,余数+1
        if tmp:
            num_pages+=1
        self.num_pages=num_pages

        # 最多显示的页数
        self.max_pager_num=max_pager_num
        self.five_five_open=int(self.max_pager_num-1)/2  分页显示情况



    @property
    def start(self):
        return (self.current_page-1)*self.per_page

    @property
    def end(self):
        return self.current_page*self.per_page



    # 总页数小于当前显示页数
    def page_html(self):
        if self.num_pages<=self.max_pager_num:
            pager_start=1
            pager_end=self.num_pages+1
        #  当前显示的页数小于five_five_open的数字
        else:
            if self.current_page<=self.five_five_open:
                pager_start=1
                pager_end=self.num_pages+1
            elif (self.current_page+self.five_five_open)>=self.num_pages:
                pager_start=self.num_pages-self.max_pager_num+1
                pager_end=self.num_pages+1
            else:
                pager_start=self.current_page-self.five_five_open
                pager_end=self.current_page+self.five_five_open+1



        page_html_list=[]

        first_page = '<nav aria-label="Page navigation"><ul class="pagination"><li><a href="?page=%s">首页</a></li>' % (
        1,)
        page_html_list.append(first_page)

        if self.current_page <= 1:
            prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
        else:
            prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)

        page_html_list.append(prev_page)


        for i in range(pager_start,pager_end):
            if i == self.current_page:
                temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
            else:
                temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
            page_html_list.append(temp)


        if self.current_page >= self.num_pages:
            next_page = '<li class="disabled"><a href="#">下一页</a></li>'
        else:
            next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
        page_html_list.append(next_page)

        last_page = '<li><a href="?page=%s">尾页</a></li></ul></nav>' % (self.num_pages)
        page_html_list.append(last_page)

        return ''.join(page_html_list)

前端页面逻辑

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!-- 最新版本的 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>

<ul>
    {% for book in book_list %}
    <li>{{ book.title }}---{{ book.price }}</li>
    {% endfor %}
</ul>

#调通pagination对象的page_html方法通过safe进行转义
{{ pagination.page_html|safe }}




</body>
</html>