zoukankan      html  css  js  c++  java
  • day 61 Django基础之django分页

     

    Django基础之django分页

    一、Django的内置分页器(paginator)

      

    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})
    复制代码
    复制代码

      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>
    复制代码
    复制代码

      扩展

    复制代码
    复制代码
    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())
    复制代码

    二、自定义分页

      当数据库中数据有很多,我们通常会在前端页面做分页展示。

      分页的数据可以在前端页面实现,也可以在后端实现分页。

      后端实现分页的原理就是每次只请求一页数据。

      准备工作

      我们使用脚本批量创建一些测试数据(将下面的代码保存到bulk_create.py文件中放到Django项目的根目录,直接执行即可。):

    复制代码
    import os
    
    if __name__ == "__main__":
        os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
    
        import django
        django.setup()
    
        from app01 import models
        bulk_obj = (models.Publisher(name='第{}出版社'.format(i)) for i in range(300))
        models.Publisher.objects.bulk_create(bulk_obj) #批量添加,注意写法
    复制代码

      看下面几个版本的分页:


    def publisher_list(request):
        # 从URL中取当前访问的页码数
        try:
            current_page = int(request.GET.get('page'))
        except Exception as e:
            # 取不到或者页码数不是数字都默认展示第1页
            current_page = 1
        # 总数据量
        total_count = models.Publisher.objects.count()
        # 定义每页显示多少条数据
        per_page = 10
        # 计算出总页码数
        total_page, more = divmod(total_count, per_page)
        if more:
            total_page += 1
        # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
        max_show = 11
        half_show = max_show // 2
        # 计算一下页面显示的页码范围
        if total_page <= max_show:  # 总页码数小于最大显示页码数
            page_start = 1
            page_end = total_page
        elif current_page + half_show >= total_page:  # 右边越界
            page_end = total_page
            page_start = total_page - max_show
        elif current_page - half_show <= 1:  # 左边越界
            page_start = 1
            page_end = max_show
        else:  # 正常页码区间
            page_start = current_page - half_show
            page_end = current_page + half_show
        # 数据索引起始位置
        data_start = (current_page-1) * per_page
        data_end = current_page * per_page
    
        publisher_list = models.Publisher.objects.all()[data_start:data_end]
    
        # 生成页面上显示的页码
        page_html_list = []
        page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
        # 加首页
        first_li = '<li><a href="/publisher_list/?page=1">首页</a></li>'
        page_html_list.append(first_li)
        # 加上一页
        if current_page == 1:
            prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
        else:
            prev_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(current_page - 1)
        page_html_list.append(prev_li)
        for i in range(page_start, page_end + 1):
            if i == current_page:
                li_tag = '<li class="active"><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
            else:
                li_tag = '<li><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
            page_html_list.append(li_tag)
        # 加下一页
        if current_page == total_page:
            next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
        else:
            next_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(current_page + 1)
        page_html_list.append(next_li)
        # 加尾页
        page_end_li = '<li><a href="/publisher_list/?page={}">尾页</a></li>'.format(total_page)
        page_html_list.append(page_end_li)
        page_html_list.append('</ul></nav>')
        page_html = "".join(page_html_list)
        return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})
    复制代码
    def publisher_list(request):
        # 从URL中取当前访问的页码数
        try:
            current_page = int(request.GET.get('page'))
        except Exception as e:
            # 取不到或者页码数不是数字都默认展示第1页
            current_page = 1
        # 总数据量
        total_count = models.Publisher.objects.count()
        # 定义每页显示多少条数据
        per_page = 10
        # 计算出总页码数
        total_page, more = divmod(total_count, per_page)
        if more:
            total_page += 1
        # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
        max_show = 11
        half_show = max_show // 2
        # 计算一下页面显示的页码范围
        if total_page <= max_show:  # 总页码数小于最大显示页码数
            page_start = 1
            page_end = total_page
        elif current_page + half_show >= total_page:  # 右边越界
            page_end = total_page
            page_start = total_page - max_show
        elif current_page - half_show <= 1:  # 左边越界
            page_start = 1
            page_end = max_show
        else:  # 正常页码区间
            page_start = current_page - half_show
            page_end = current_page + half_show
        # 数据索引起始位置
        data_start = (current_page-1) * per_page
        data_end = current_page * per_page
    
        publisher_list = models.Publisher.objects.all()[data_start:data_end]
    
        # 生成页面上显示的页码
        page_html_list = []
        page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
        # 加首页
        first_li = '<li><a href="/publisher_list/?page=1">首页</a></li>'
        page_html_list.append(first_li)
        # 加上一页
        if current_page == 1:
            prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
        else:
            prev_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(current_page - 1)
        page_html_list.append(prev_li)
        for i in range(page_start, page_end + 1):
            if i == current_page:
                li_tag = '<li class="active"><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
            else:
                li_tag = '<li><a href="/publisher_list/?page={0}">{0}</a></li>'.format(i)
            page_html_list.append(li_tag)
        # 加下一页
        if current_page == total_page:
            next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
        else:
            next_li = '<li><a href="/publisher_list/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(current_page + 1)
        page_html_list.append(next_li)
        # 加尾页
        page_end_li = '<li><a href="/publisher_list/?page={}">尾页</a></li>'.format(total_page)
        page_html_list.append(page_end_li)
        page_html_list.append('</ul></nav>')
        page_html = "".join(page_html_list)
        return render(request, "publisher_list.html", {"publisher_list": publisher_list, "page_html": page_html})
    复制代码
    class Pagination(object):
        """自定义分页(Bootstrap版)"""
        def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
            """
            :param current_page: 当前请求的页码
            :param total_count: 总数据量
            :param base_url: 请求的URL
            :param per_page: 每页显示的数据量,默认值为10
            :param max_show: 页面上最多显示多少个页码,默认值为11
            """
            try:
                self.current_page = int(current_page)
            except Exception as e:
                # 取不到或者页码数不是数字都默认展示第1页
                self.current_page = 1
            # 定义每页显示多少条数据
            self.per_page = per_page
            # 计算出总页码数
            total_page, more = divmod(total_count, per_page)
            if more:
                total_page += 1
            self.total_page = total_page
            # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
            self.max_show = max_show
            self.half_show = max_show // 2
            self.base_url = base_url
    
        @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.total_page <= self.max_show:  # 总页码数小于最大显示页码数
                page_start = 1
                page_end = self.total_page
            elif self.current_page + self.half_show >= self.total_page:  # 右边越界
                page_end = self.total_page
                page_start = self.total_page - self.max_show
            elif self.current_page - self.half_show <= 1:  # 左边越界
                page_start = 1
                page_end = self.max_show
            else:  # 正常页码区间
                page_start = self.current_page - self.half_show
                page_end = self.current_page + self.half_show
            # 生成页面上显示的页码
            page_html_list = []
            page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
            # 加首页
            first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
            page_html_list.append(first_li)
            # 加上一页
            if self.current_page == 1:
                prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
            else:
                prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                    self.base_url, self.current_page - 1)
            page_html_list.append(prev_li)
            for i in range(page_start, page_end + 1):
                if i == self.current_page:
                    li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                else:
                    li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                page_html_list.append(li_tag)
            # 加下一页
            if self.current_page == self.total_page:
                next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
            else:
                next_li = '<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                    self.base_url, self.current_page + 1)
            page_html_list.append(next_li)
            # 加尾页
            page_end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
            page_html_list.append(page_end_li)
            page_html_list.append('</ul></nav>')
            return "".join(page_html_list
    复制代码
    class Pagination(object):
        """自定义分页(Bootstrap版)"""
        def __init__(self, current_page, total_count, base_url, per_page=10, max_show=11):
            """
            :param current_page: 当前请求的页码
            :param total_count: 总数据量
            :param base_url: 请求的URL
            :param per_page: 每页显示的数据量,默认值为10
            :param max_show: 页面上最多显示多少个页码,默认值为11
            """
            try:
                self.current_page = int(current_page)
            except Exception as e:
                # 取不到或者页码数不是数字都默认展示第1页
                self.current_page = 1
            # 定义每页显示多少条数据
            self.per_page = per_page
            # 计算出总页码数
            total_page, more = divmod(total_count, per_page)
            if more:
                total_page += 1
            self.total_page = total_page
            # 定义页面上最多显示多少页码(为了左右对称,一般设为奇数)
            self.max_show = max_show
            self.half_show = max_show // 2
            self.base_url = base_url
    
        @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.total_page <= self.max_show:  # 总页码数小于最大显示页码数
                page_start = 1
                page_end = self.total_page
            elif self.current_page + self.half_show >= self.total_page:  # 右边越界
                page_end = self.total_page
                page_start = self.total_page - self.max_show
            elif self.current_page - self.half_show <= 1:  # 左边越界
                page_start = 1
                page_end = self.max_show
            else:  # 正常页码区间
                page_start = self.current_page - self.half_show
                page_end = self.current_page + self.half_show
            # 生成页面上显示的页码
            page_html_list = []
            page_html_list.append('<nav aria-label="Page navigation"><ul class="pagination">')
            # 加首页
            first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
            page_html_list.append(first_li)
            # 加上一页
            if self.current_page == 1:
                prev_li = '<li><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'
            else:
                prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(
                    self.base_url, self.current_page - 1)
            page_html_list.append(prev_li)
            for i in range(page_start, page_end + 1):
                if i == self.current_page:
                    li_tag = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                else:
                    li_tag = '<li><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
                page_html_list.append(li_tag)
            # 加下一页
            if self.current_page == self.total_page:
                next_li = '<li><a href="#"><span aria-hidden="true">&raquo;</span></a></li>'
            else:
                next_li = '<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(
                    self.base_url, self.current_page + 1)
            page_html_list.append(next_li)
            # 加尾页
            page_end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
            page_html_list.append(page_end_li)
            page_html_list.append('</ul></nav>')
            return "".join(page_html_list)
    复制代码

    def publisher_list(request):
        # 从URL中取当前访问的页码数
        current_page = int(request.GET.get('page'))
        # 比len(models.Publisher.objects.all())更高效
        total_count = models.Publisher.objects.count()
        page_obj = Pagination(current_page, total_count, request.path_info)
        data = models.Publisher.objects.all()[page_obj.start:page_obj.end]
        page_html = page_obj.page_html()
        return render(request, "publisher_list.html", {"publisher_list": data, "page_html": page_html})
    复制代码
    def publisher_list(request):
        # 从URL中取当前访问的页码数
        current_page = int(request.GET.get('page'))
        # 比len(models.Publisher.objects.all())更高效
        total_count = models.Publisher.objects.count()
        page_obj = Pagination(current_page, total_count, request.path_info)
        data = models.Publisher.objects.all()[page_obj.start:page_obj.end]
        page_html = page_obj.page_html()
        return render(request, "publisher_list.html", {"publisher_list": data, "page_html": page_html})
    复制代码

      再来一版django内置分页器的分页

    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    L = []
    for i in range(999):
        L.append(i)
    
    def index(request):
        current_page = request.GET.get('p')
    
        paginator = Paginator(L, 10)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)
            # has_next              是否有下一页
            # next_page_number      下一页页码
            # has_previous          是否有上一页
            # previous_page_number  上一页页码
            # object_list           分页之后的数据列表
            # number                当前页
            # paginator             paginator对象
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)
        return render(request, 'index.html', {'posts': posts})

    复制代码
    from django.shortcuts import render
    from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
    
    L = []
    for i in range(999):
        L.append(i)
    
    def index(request):
        current_page = request.GET.get('p')
    
        paginator = Paginator(L, 10)
        # per_page: 每页显示条目数量
        # count:    数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围,如: (1,10),(1,200)
        # page:     page对象
        try:
            posts = paginator.page(current_page)
            # has_next              是否有下一页
            # next_page_number      下一页页码
            # has_previous          是否有上一页
            # previous_page_number  上一页页码
            # object_list           分页之后的数据列表
            # number                当前页
            # paginator             paginator对象
        except PageNotAnInteger:
            posts = paginator.page(1)
        except EmptyPage:
            posts = paginator.page(paginator.num_pages)
        return render(request, 'index.html', {'posts': posts})
    复制代码
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <ul>
        {% for item in posts %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    
    <div class="pagination">
          <span class="step-links">
            {% if posts.has_previous %}
                <a href="?p={{ posts.previous_page_number }}">Previous</a>
            {% endif %}
              <span class="current">
                Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
              </span>
              {% if posts.has_next %}
                  <a href="?p={{ posts.next_page_number }}">Next</a>
              {% endif %}
          </span>
    
    </div>
    </body>
    </html>

    复制代码
    <!DOCTYPE html>
    <html>
    <head lang="en">
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
    <ul>
        {% for item in posts %}
            <li>{{ item }}</li>
        {% endfor %}
    </ul>
    
    <div class="pagination">
          <span class="step-links">
            {% if posts.has_previous %}
                <a href="?p={{ posts.previous_page_number }}">Previous</a>
            {% endif %}
              <span class="current">
                Page {{ posts.number }} of {{ posts.paginator.num_pages }}.
              </span>
              {% if posts.has_next %}
                  <a href="?p={{ posts.next_page_number }}">Next</a>
              {% endif %}
          </span>
    
    </div>
    </body>
    </html>
    复制代码
     
     
     
     
  • 相关阅读:
    leetcode 309. Best Time to Buy and Sell Stock with Cooldown
    leetcode 714. Best Time to Buy and Sell Stock with Transaction Fee
    leetcode 32. Longest Valid Parentheses
    leetcode 224. Basic Calculator
    leetcode 540. Single Element in a Sorted Array
    leetcode 109. Convert Sorted List to Binary Search Tree
    leetcode 3. Longest Substring Without Repeating Characters
    leetcode 84. Largest Rectangle in Histogram
    leetcode 338. Counting Bits
    git教程之回到过去,版本对比
  • 原文地址:https://www.cnblogs.com/yanghongtao/p/10914790.html
Copyright © 2011-2022 走看看