• Django(分页)


    day71

    参考:http://www.cnblogs.com/liwenzhou/p/8660826.html#autoid-4-1-0

    day71

    参考:http://www.cnblogs.com/liwenzhou/p/8343243.html#autoid-0-4-5

    分页

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

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

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

    准备工作

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

     1 import os
     2 
     3 if __name__ == "__main__":
     4     os.environ.setdefault("DJANGO_SETTINGS_MODULE", "about_orm.settings")
     5 
     6     import django
     7     django.setup()
     8 
     9     from app01 import models
    10     bulk_obj = (models.Publisher(name='沙河第{}出版社'.format(i)) for i in range(300))
    11     models.Publisher.objects.bulk_create(bulk_obj)

    不分页

     

    分页代码分析:

    数据格式:

    显示内容部分:

    导航条部分:

    导航条样式

    完整代码:

    books.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>书籍列表</title>
     6     <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.css">
     7 </head>
     8 <body>
     9 <div class="container">
    10     <table class="table table-bordered">
    11         <thread>
    12             <tr>
    13                 <th>序号</th>
    14                 <th>id</th>
    15                 <th>书名</th>
    16             </tr>
    17         </thread>
    18         <tbody>
    19         {% for book in books %}
    20             <tr>
    21             <td>{{ forloop.counter }}</td>
    22             <td>{{ book.id }}</td>
    23             <td>{{ book.title }}</td>
    24             </tr>
    25         {% endfor %}
    26 
    27         </tbody>
    28     </table>
    29     <nav aria-label="Page navigation">
    30         <ul class="pagination">
    31             <li>
    32 
    33 
    34                 <li>
    35                     {{ page_html|safe }}
    36                 </li>
    37 
    38             </li>
    39         </ul>
    40     </nav>
    41 </div>
    42 
    43 </body>
    44 </html>

    views.py

     1 def books(request):
     2     # 从url取参数
     3     page_num = request.GET.get("page")  # url中拿到
     4     page_num = int(page_num)
     5 
     6     # 以上决定的是页面显示的内容
     7     # 一下决定导航条的内容
     8     # 每一页显示多少条数据
     9     per_page = 10
    10     # 总数据条数
    11     total_count = models.Book.objects.all().count()
    12     # 总共需要多少页码显示
    13     total_page, m = divmod(total_count, per_page)  # 共total_count条数据, 每页per_page条显示
    14     if m:  # 有值 需加1
    15         total_page += 1  # 共需total_count+=1页显示
    16     try:
    17         page_num = int(page_num)
    18         # 如果页数超过最大页码数,返回最后一页
    19         if page_num > total_page:
    20             page_num = total_page
    21         if page_num < 1:
    22             page_num = 1
    23     except Exception as e:
    24         page_num = 1
    25 
    26     # 定义两个变量
    27     data_start = (page_num - 1) * 10
    28     data_end = page_num * 10
    29     all_book = models.Book.objects.all()[data_start:data_end]
    30 
    31     # 页面上总共展示多少页码
    32     max_page = 11
    33     if total_page < max_page: # 总页数过小,小于设定
    34         max_page = total_page
    35     half_max_page = max_page // 2
    36     # 页面上展示的页码从哪开始
    37     page_start = page_num - half_max_page
    38     # 到哪儿结束
    39     page_end = page_num + half_max_page
    40     # 如果起始值小于等于1
    41     if page_start <= 1:
    42         page_start = 1
    43         page_end = max_page
    44     # 如果当前页加一半比总页码数还大
    45     if page_end >= total_page:
    46         page_end = total_page
    47         page_start = total_page - max_page + 1   # 导航条显示数量必须相同
    48 
    49 
    50 
    51     # 自己拼接分页的HTML代码
    52     html_str_list = []
    53     # 加上第一页
    54     html_str_list.append('<li><a href="/books/?page=1">首页</a></li>')
    55     # 加上一个上一页的标签                                                                     只要中间页往前移就整体往前移一页
    56     #html_str_list.append('<li><a href="/books/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(page_num-1))
    57     if page_num == 1: # 如果已经是第一页了就不在跳转 #
    58         html_str_list.append(
    59             '<li class="disabled"><a href="#"><span aria-hidden="true">&laquo;</span></a></li>')
    60     else:
    61         html_str_list.append(
    62             '<li><a href="/books/?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format(page_num - 1))
    63     for i in range(page_start, page_end+1):
    64         # # 跳转内容带 page 巧妙! page决定了显示哪些内容在页面上
    65         if i == page_num:
    66                         # 当前页高亮
    67             tmp = '<li class="active"><a href="/books/?page={0}">{0}</a></li>'.format(i)
    68         else:
    69             tmp = '<li><a href="/books/?page={0}">{0}</a></li>'.format(i)
    70         html_str_list.append(tmp)
    71     # 加上一个下一页的标签                               只要中间页往前移就整体往前移一页
    72     if page_num == total_page: # 如果已经是最后一页了就不在跳转 #
    73         html_str_list.append(
    74             '<li class="disabled"><a href="#"><span aria-hidden="true">&raquo;</span></a></li>')
    75     else:
    76         html_str_list.append(
    77             '<li><a href="/books/?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format(page_num + 1))
    78     # 加上尾页
    79     html_str_list.append('<li><a href="/books/?page={}">尾页</a></li>'.format(total_page))
    80     page_html = "".join(html_str_list)
    81     return render(request, "books.html", {"books": all_book, "page_html": page_html})

    将以上内容封装成通用模块

    @property

    以下为完整程序:

    views.py

    def depts(request):
        # 从URL取参数
        page_num = request.GET.get("page")
        print(page_num, type(page_num))
        # 总数据是多少
        total_count = models.Dept.objects.all().count()
        from utils.mypage import Page # 调用自己写的模块
        # 创建对象
        page_obj = Page(page_num, total_count, per_page=10, url_prefix="/depts/", max_page=11, )
    
        ret = models.Dept.objects.all()[page_obj.start:page_obj.end]  # 调用该对象中的方法
        print(ret)
        # 使用对象方法
        page_html = page_obj.page_html()
        return render(request, "dept.html", {"depts": ret, "page_html": page_html})

    mypage.py

     1 class Page():
     2                                              #  路径
     3     def __init__(self, page_num, total_count, url_prefix, per_page=10, max_page=11):
     4         """
     5 
     6         :param page_num: 当前页码数
     7         :param total_count: 数据总数
     8         :param url_prefix: a标签href的前缀
     9         :param per_page: 每页显示多少条数据
    10         :param max_page: 页面上最多显示几个页码
    11         """
    12         self.url_prefix = url_prefix
    13         self.max_page = max_page
    14         # 每一页显示多少条数据
    15         # 总共需要多少页码来展示
    16         total_page, m = divmod(total_count, per_page)
    17         if m:
    18             total_page += 1
    19         self.total_page = total_page
    20 
    21         try:
    22             page_num = int(page_num)
    23             # 如果输入的页码数超过了最大的页码数,默认返回最后一页
    24             if page_num > total_page:
    25                 page_num = total_page
    26         except Exception as e:
    27             # 当输入的页码不是正经数字的时候 默认返回第一页的数据
    28             page_num = 1
    29         self.page_num = page_num
    30 
    31         # 定义两个变量保存数据从哪儿取到哪儿    决定显示的数据
    32         self.data_start = (page_num - 1) * 10
    33         self.data_end = page_num * 10
    34 
    35         # 页面上总共展示多少页码
    36         if total_page < self.max_page:
    37             self.max_page = total_page
    38 
    39         half_max_page = self.max_page // 2
    40         # 页面上展示的页码从哪儿开始
    41         page_start = page_num - half_max_page
    42         # 页面上展示的页码到哪儿结束
    43         page_end = page_num + half_max_page
    44         # 如果当前页减一半 比1还小
    45         if page_start <= 1:
    46             page_start = 1
    47             page_end = self.max_page
    48         # 如果 当前页 加 一半 比总页码数还大
    49         if page_end >= total_page:
    50             page_end = total_page
    51             page_start = total_page - self.max_page + 1
    52         self.page_start = page_start
    53         self.page_end = page_end
    54 
    55     @property  # page_obj.start 表示返回数据本身
    56     def start(self):   # 这部分是显示内容的部分,并不是导航条的部分    显示数据的开始与结束
    57         return self.data_start
    58 
    59     @property
    60     def end(self):
    61         return self.data_end
    62 
    63 
    64     def page_html(self):
    65         # 自己拼接分页的HTML代码
    66         html_str_list = []
    67         # 加上第一页
    68         html_str_list.append('<li><a href="{}?page=1">首页</a></li>'.format( self.url_prefix))
    69 
    70         # 判断一下 如果是第一页,就没有上一页
    71         if self.page_num <= 1:
    72             html_str_list.append('<li class="disabled"><a href="#"><span aria-hidden="true">&laquo;</span></a></li>'.format(self.page_num-1))
    73         else:
    74             # 加一个上一页的标签
    75             html_str_list.append('<li><a href="{}?page={}"><span aria-hidden="true">&laquo;</span></a></li>'.format( self.url_prefix, self.page_num-1))
    76 
    77         for i in range(self.page_start, self.page_end+1):
    78             # 如果是当前页就加一个active样式类
    79             if i == self.page_num:                                              #路径和页码
    80                 tmp = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.url_prefix, i)
    81             else:
    82                 tmp = '<li><a href="{0}?page={1}">{1}</a></li>'.format( self.url_prefix, i)
    83 
    84             html_str_list.append(tmp)
    85 
    86         # 加一个下一页的按钮
    87         # 判断,如果是最后一页,就没有下一页
    88         if self.page_num >= self.total_page:
    89             html_str_list.append('<li class="disabled"><a href="#"><span aria-hidden="true">&raquo;</span></a></li>')
    90         else:
    91             html_str_list.append('<li><a href="{}?page={}"><span aria-hidden="true">&raquo;</span></a></li>'.format( self.url_prefix, self.page_num+1))
    92         # 加最后一页
    93         html_str_list.append('<li><a href="{}?page={}">尾页</a></li>'.format( self.url_prefix, self.total_page))
    94 
    95         page_html = "".join(html_str_list)
    96         return page_html

    含三个方法,前两个获得显示数据的起始与结束,第三个获得导航条需要显示的内容。

    dept.html

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>部门列表</title>
     6     <link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
     7 </head>
     8 <body>
     9 
    10 <div class="container">
    11     <table class="table table-bordered">
    12       <thead>
    13         <tr>
    14             <th>序号</th>
    15             <th>id</th>
    16             <th>部门名</th>
    17         </tr>
    18       </thead>
    19         <tbody>
    20         {% for dept in depts %}
    21             <tr>
    22             <td>{{ forloop.counter }}</td>
    23             <td>{{ dept.id }}</td>
    24             <td>{{ dept.name }}</td>
    25             </tr>
    26         {% endfor %}
    27 
    28         </tbody>
    29 </table>
    30 <nav aria-label="Page navigation">
    31   <ul class="pagination">
    32         {{ page_html|safe }}
    33   </ul>
    34 </nav>
    35 </div>
    36 </body>
    37 </html>

    效果:

  • 相关阅读:
    我开博客了,啦啦啦.
    cf593div2
    Comet OJ
    cf591div2abc
    cfround586ac
    cf589div2
    cf573div2
    Codeforces Round #569 (Div. 2)
    uva11729 水题
    luogu1984 [SDOI2008] 烧水问题
  • 原文地址:https://www.cnblogs.com/112358nizhipeng/p/10495597.html
Copyright © 2020-2023  润新知