• Django组件分页器


    1 Django的分页器(paginator)简介

    在页面显示分页数据,需要用到Django分页器组件

    from django.core.paginator import Paginator

    Paginator对象:    paginator = Paginator(user_list, 10)
    # per_page: 每页显示条目数量
    # count:    数据总个数
    # num_pages:总页数
    # page_range:总页数的索引范围,如: (1,10),(1,200)
    # page:     page对象    
    page对象:page=paginator.page(1)
    # has_next              是否有下一页
    # next_page_number      下一页页码
    # has_previous          是否有上一页
    # previous_page_number  上一页页码
    # object_list           分页之后的数据列表
    # number                当前页
    # paginator             paginator对象

    2 应用View层

    from django.shortcuts import render,HttpResponse
    
    # Create your views here.
    from app01.models import *
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    def index(request):
    
        '''
        批量导入数据:
    
        Booklist=[]
        for i in range(100):
            Booklist.append(Book(title="book"+str(i),price=30+i*i))
        Book.objects.bulk_create(Booklist)
        '''
    
        '''
    分页器的使用:
    
        book_list=Book.objects.all()
    
        paginator = Paginator(book_list, 10)
    
        print("count:",paginator.count)           #数据总数
        print("num_pages",paginator.num_pages)    #总页数
        print("page_range",paginator.page_range)  #页码的列表
    
    
    
        page1=paginator.page(1) #第1页的page对象
        for i in page1:         #遍历第1页的所有数据对象
            print(i)
    
        print(page1.object_list) #第1页的所有数据
    
    
        page2=paginator.page(2)
    
        print(page2.has_next())            #是否有下一页
        print(page2.next_page_number())    #下一页的页码
        print(page2.has_previous())        #是否有上一页
        print(page2.previous_page_number()) #上一页的页码
    
    
    
        # 抛错
        #page=paginator.page(12)   # error:EmptyPage
    
        #page=paginator.page("z")   # error:PageNotAnInteger
    
        '''
    
    
        book_list=Book.objects.all()
    
        paginator = Paginator(book_list, 10)
        page = request.GET.get('page',1)
        currentPage=int(page)
    
    
        try:
            print(page)
            book_list = paginator.page(page)
        except PageNotAnInteger:
            book_list = paginator.page(1)
        except EmptyPage:
            book_list = paginator.page(paginator.num_pages)
    
    
        return render(request,"index.html",{"book_list":book_list,"paginator":paginator,"currentPage":currentPage})

    3 模版层 index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css" 
        integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
    
    <div class="container">
    
        <h4>分页器</h4>
        <ul>
    
            {% for book in book_list %}
                 <li>{{ book.title }} -----{{ book.price }}</li>
            {% endfor %}
    
         </ul>
    
    
        <ul class="pagination" id="pager">
    
                     {% if book_list.has_previous %}
                        <li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
                     {% else %}
                        <li class="previous disabled"><a href="#">上一页</a></li>
                     {% endif %}
    
    
                     {% for num in paginator.page_range %}
    
                         {% if num == currentPage %}
                           <li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
                         {% else %}
                           <li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>
    
                         {% endif %}
                     {% endfor %}
    
    
    
                     {% if book_list.has_next %}
                        <li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
                     {% else %}
                        <li class="next disabled"><a href="#">下一页</a></li>
                     {% endif %}
    
                </ul>
    </div>
    
    
    
    </body>
    </html>

    4 扩展

    '''
        显示左5,右5,总共11个页,
        1 如果总页码大于11
            1.1 if 当前页码减5小于1,要生成1到12的列表(顾头不顾尾,共11个页码)
                page_range=range(1,12)
            1.2 elif 当前页码+5大于总页码,生成当前页码减10,到当前页码加1的列表(顾头不顾尾,共11个页码)
                page_range=range(paginator.num_pages-10,paginator.num_pages+1)
            1.3 else 生成当前页码-5,到当前页码+6的列表
                page_range=range(current_page_num-5,current_page_num+6)
        2 其它情况,生成的列表就是pageinator的page_range
            page_range=paginator.page_range
    
        '''
    核心逻辑
    def index(request):
    
    
        book_list=Book.objects.all()
    
        paginator = Paginator(book_list, 15)
        page = request.GET.get('page',1)
        currentPage=int(page)
    
        #  如果页数十分多时,换另外一种显示方式
    if paginator.num_pages>11: if currentPage-5<1: pageRange=range(1,11) elif currentPage+5>paginator.num_pages: pageRange=range(currentPage-5,paginator.num_pages+1) else: pageRange=range(currentPage-5,currentPage+5) else: pageRange=paginator.page_range try: print(page) book_list = paginator.page(page) except PageNotAnInteger: book_list = paginator.page(1) except EmptyPage: book_list = paginator.page(paginator.num_pages) return render(request,"index.html",locals())
    def page_test(request):
        # book_list=[]
        # for i in range(100):
        #     book=Book(name='book%s'%i,price=10+i,pub_date='2018-09-18',publish_id=1)
        #     book_list.append(book)
        # Book.objects.bulk_create(book_list,10)
        book_list=Book.objects.all()
        # 生成paginator对象,传入书籍列表,每页10条数据
        paginator=Paginator(book_list,3)
        # 总页码数
        print(paginator.num_pages)
        # 页码列表
        print(paginator.page_range)
        # 总数据
        print(paginator.count)
        # 获取页面传来的页码
        current_page=int(request.GET.get('page',1))
        page_range=[]
        # 左5 右5
    
        # 获取页面传来的页码的page对象
        try:
            page=paginator.page(current_page)
            # print(page.has_next())            #是否有下一页
            # print(page.next_page_number())    #下一页的页码
            # print(page.has_previous())        #是否有上一页
            # print(page.previous_page_number()) #上一页的页码
            # 循环打印出当页对象
            for i in page:
                print(i)
        except Exception as e:
            current_page=1
            page = paginator.page(1)
        if paginator.num_pages>11:
            if current_page+5>paginator.num_pages:
                page_range=range(paginator.num_pages-10,paginator.num_pages+1)
            elif current_page-5<1:
                page_range=range(1,12)
            else:
                page_range=range(current_page-5,current_page+6)
        else:
            page_range=paginator.page_range
    
    
    
        return render(request,'page_test.html',locals())
    views
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.min.css">
        <title>Title</title>
    </head>
    <body>
    
    <ul>
    
        {% for foo in page %}
            <li>{{ foo.name }}</li>
    
        {% endfor %}
    
    </ul>
    <nav aria-label="Page navigation">
        <ul class="pagination">
            {% if page.has_previous %}
                <li>
                    <a href="/page_test/?page={{ page.previous_page_number }}" aria-label="Previous">
                        <span aria-hidden="true">上一页</span>
                    </a>
                </li>
            {% else %}
                <li class="disabled">
                    <a href="#" aria-label="Previous">
                        <span aria-hidden="true">上一页</span>
                    </a>
                </li>
            {% endif %}
    
            {% for foo in page_range %}
                {% if current_page == foo %}
                    <li class="active"><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li>
                {% else %}
                    <li><a href="/page_test/?page={{ foo }}">{{ foo }}</a></li>
                {% endif %}
    
            {% endfor %}
            {% if page.has_next %}
                <li>
                    <a href="/page_test/?page={{ page.next_page_number }}" aria-label="Next">
                        <span aria-hidden="true">下一页</span>
                    </a>
                </li>
            {% else %}
                <li class="disabled">
                    <a href="#" aria-label="Next">
                        <span aria-hidden="true">下一页</span>
                    </a>
                </li>
    
            {% endif %}
    
        </ul>
    </nav>
    
    
    </body>
    </html>
    模版

    使用:

    #views.py
    from django.shortcuts import render, HttpResponse
     
    # Create your views here.
    from app01.models import *
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
     
    def index(request):
        obj_list = Book.objects.all()
        paginator = Paginator(obj_list,9)  # 每页显示行数
        try:
            current_page = int(request.GET.get("page"))  # 防止非数字
        except:
            current_page = 1
        #########################################################
     
        show_page = 11  #默认显示页数
        half = int((show_page - 1) / 2)
        all_pager = paginator.num_pages #总页数
     
        # 如果数据总页数 < 11
        if all_pager < show_page:
            begin = 1
            stop = all_pager + 1
        # 如果数据总页数 > 11
        else:
            # 如果当前页 <=5,永远显示1,11
            if current_page <= half:
                begin = 1
                stop = show_page + 1
            else:
                if current_page + half > all_pager:
                    begin = all_pager - show_page + 1
                    stop = all_pager + 1
                else:
                    begin = current_page - half
                    stop = current_page + half + 1
        page_range = range(begin,stop)
        #########################################################
        try:
            obj_list = paginator.page(current_page)
        except PageNotAnInteger:
            obj_list = paginator.page(1)
        except EmptyPage:
            obj_list = paginator.page(paginator.num_pages)
     
        # return render(request,"index.html",locals())
        return render(request, "index.html", {"obj_list": obj_list, "current_page": current_page, "page_range": page_range})
     
    '''
    批量导入数据:
        Booklist=[]
        for i in range(100):
            Booklist.append(Book(title="book"+str(i),price=30+i*i))
        Book.objects.bulk_create(Booklist)
    分页器的使用:
        obj_list=Book.objects.all()
        paginator = Paginator(obj_list, 10)     #每页显示10条
     
        print("count:",paginator.count)           #数据总数
        print("num_pages",paginator.num_pages)    #总页数
        print("page_range",paginator.page_range)  #页码的列表
     
        page1=paginator.page(1) #第1页的page对象
     
        #显示某一页具体数据的两种方式:
        #方式1
        for i in page1:         #遍历第1页的所有数据对象
            print(i)
     
        #方式2
        print(page1.object_list) #第1页的所有数据
     
        page2=paginator.page(2)
        print(page2.has_next())            #是否有下一页
        print(page2.next_page_number())    #下一页的页码
        print(page2.has_previous())        #是否有上一页
        print(page2.previous_page_number()) #上一页的页码
     
        #当前页
        current_page=int(request.GET.get("page",1))
        obj_list=paginator.page(current_page)
        for i in obj_list:         #遍历当前页的所有数据对象
            print(i)
     
        # 抛错
        #page=paginator.page(12)   # error:EmptyPage
        #page=paginator.page("z")   # error:PageNotAnInteger
     
    '''
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
        <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
              integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
    </head>
    <body>
     
    <div class="container">
     
        <h4>分页器</h4>
        <ul>
            {% for row in obj_list %}
                 <li>{{ row.title }} -----{{ row.price }}</li>
            {% endfor %}
         </ul>
     
    <nav aria-label="Page navigation">
        <ul class="pagination" id="pager">
                     {% if obj_list.has_previous %}
                        <li class="previous"><a href="?page={{ obj_list.previous_page_number }}">上一页</a></li>
                     {% else %}
                        <li class="previous disabled"><a href="">上一页</a></li>
                     {% endif %}
     
                     {% for num in page_range %}
                         {% if num == current_page %}
                           <li class="item active"><a href="?page={{ num }}">{{ num }}</a></li>
                         {% else %}
                           <li class="item"><a href="?page={{ num }}">{{ num }}</a></li>
                         {% endif %}
                     {% endfor %}
     
                     {% if obj_list.has_next %}
                        <li class="next"><a href="?page={{ obj_list.next_page_number }}">下一页</a></li>
                     {% else %}
                        <li class="next disabled"><a href="">下一页</a></li>
                     {% endif %}
         </ul>
    </nav>
    </div>
     
    </body>
    </html>
    index.html

    自定义分页

    """
    分页组件
    """
    
    
    class Pagination(object):
        def __init__(self, current_page, all_count, base_url, query_params, per_page=20, pager_page_count=11):
            """
            分页初始化
            :param current_page: 当前页码
            :param per_page: 每页显示数据条数
            :param all_count: 数据库中总条数
            :param base_url: 基础URL
            :param query_params: QueryDict对象,内部含所有当前URL的原条件
            :param pager_page_count: 页面上最多显示的页码数量
            """
            self.base_url = base_url
            try:
                self.current_page = int(current_page)
                if self.current_page <= 0:
                    raise Exception()
            except Exception as e:
                self.current_page = 1
            self.query_params = query_params
            self.per_page = per_page
            self.all_count = all_count
            self.pager_page_count = pager_page_count
            pager_count, b = divmod(all_count, per_page)
            if b != 0:
                pager_count += 1
            self.pager_count = pager_count
    
            half_pager_page_count = int(pager_page_count / 2)
            self.half_pager_page_count = half_pager_page_count
    
        @property
        def start(self):
            """
            数据获取值起始索引
            :return:
            """
            return (self.current_page - 1) * self.per_page
    
        @property
        def end(self):
            """
            数据获取值结束索引
            :return:
            """
            return self.current_page * self.per_page
    
        def page_html(self):
            """
            生成HTML页码
            :return:
            """
            # 如果数据总页码pager_count<11 pager_page_count
            if self.pager_count < self.pager_page_count:
                pager_start = 1
                pager_end = self.pager_count
            else:
                # 数据页码已经超过11
                # 判断: 如果当前页 <= 5 half_pager_page_count
                if self.current_page <= self.half_pager_page_count:
                    pager_start = 1
                    pager_end = self.pager_page_count
                else:
                    # 如果: 当前页+5 > 总页码
                    if (self.current_page + self.half_pager_page_count) > self.pager_count:
                        pager_end = self.pager_count
                        pager_start = self.pager_count - self.pager_page_count + 1
                    else:
                        pager_start = self.current_page - self.half_pager_page_count
                        pager_end = self.current_page + self.half_pager_page_count
    
            page_list = []
    
            if self.current_page <= 1:
                prev = '<li><a href="#">上一页</a></li>'
            else:
                self.query_params['page'] = self.current_page - 1
                prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode())
            page_list.append(prev)
            for i in range(pager_start, pager_end + 1):
                self.query_params['page'] = i
                if self.current_page == i:
                    tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % (
                        self.base_url, self.query_params.urlencode(), i,)
                else:
                    tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,)
                page_list.append(tpl)
    
            if self.current_page >= self.pager_count:
                nex = '<li><a href="#">下一页</a></li>'
            else:
                self.query_params['page'] = self.current_page + 1
                nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),)
            page_list.append(nex)
            page_str = "".join(page_list)
            return page_str
    utils/pagination.py
    ##使用
    from django.shortcuts import render, HttpResponse
    from utils.pagination import Pagination
    def index(request):
        # ==========begin
        all_count = Book.objects.all().count()
        query_params = request.GET.copy()
        query_params._mutable = True
    
        pager = Pagination(
            current_page=request.GET.get('page'),
            all_count=all_count,
            base_url=request.path_info,
            query_params=query_params,
            per_page=20,
        )
        data_list = Book.objects.all()[pager.start:pager.end]
        # ==========end
        return render(request, 'index.html', {'data_list': data_list, 'pager': pager})
    
    
    #========模板
    """
    <nav>
          <ul class="pagination">
              {{ pager.page_html|safe }}
          </ul>
    </nav>
    """
    使用
  • 相关阅读:
    [算法] 网络中最小费用最大流
    [题解] 完美数
    [算法] 扫描线及其应用
    等待时间
    键盘操作
    鼠标操作
    元素常用操作
    元素的定位·CSS
    元素的定位·XPATH
    元素的定位
  • 原文地址:https://www.cnblogs.com/bubu99/p/10264904.html
Copyright © 2020-2023  润新知