zoukankan      html  css  js  c++  java
  • ORM之自定义分页

    ORM之自定义分页

      分页是为了在前端展示的时候,数据量过多,导致读取是不方便的问题。

      所有我们来实现一下django的分页,并把它写成一个可以在任意django项目中都可用的一个小插件。

      分页,其实就是分批次获取数据。

      在ORM中获取全部数据后分批次显示数据就是:

    models.UserInfo.object.all()[0:10]   #取0到10索引值的数据
    models.UserInfo.object.all()[10:20]   #取10到20索引值的数据

      Django自有的分页样例:需要导入 from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage

      url中的index

    url(r'^index/',views.index)

      在view中的index:

     1 def index(request):
     2     """
     3     分页
     4     :param request:
     5     :return:
     6     """
     7     from django.core.paginator import Paginator,Page,PageNotAnInteger,EmptyPage
     8     # for i in range(300):
     9     #     name = "george" + str(i)
    10     #     models.UserInfo.objects.create(name=name,age=18,ut_id=1)
    11     #这端for循环用一次生成数据即可
    12 
    13     current_page = request.GET.get("page") #取第几页
    14     user_list = models.UserInfo.objects.all()
    15     paginator = Paginator(user_list,10)
    16     #参数的意义,user_list是要分页的数据,10是一页显示的数据量
    17     #per_page:每页显示条目数量
    18     #count:数据总个数
    19     #num_pages:总页数
    20     #page_range:总页数的索引范围,如:(1,10),(1,200)
    21     #page:page对象
    22     try:
    23         posts = paginator.page(current_page) #当前显示第几页
    24         #has_next: 是否有下一页
    25         #next_page_number:下一页页码
    26         #has_previous:是否有上一页
    27         #previous_page_number:上一页页码
    28         #object_list:分页之后的数据列表
    29         #number:当前页
    30         #paginator:paginator对象
    31     except PageNotAnInteger as e:
    32         posts = paginator.page(1)
    33     except EmptyPage as e:
    34         posts = paginator.page(1)
    35     return render(request,"index.html",{"posts":posts})
    View Code

      在前端的html:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title>index</title>
     6 </head>
     7 <body>
     8     <h1>用户列表</h1>
     9     <ul>
    10         {% for row in posts.object_list %}
    11             <li>{{ row.name }}</li>
    12         {% endfor %}
    13     </ul>
    14     <div>
    15         {% if posts.hax_next %}
    16             <a href="/index/?page={{ posts.previous_page_number }}">上一页</a>
    17         {% endif %}
    18         
    19         {% for num in posts.paginator.page_range %}
    20             <a href="/index/?page={{ num }}">{{ num }}</a>
    21         {% endfor %}
    22     
    23         {% if posts.hax_next %}
    24             <a href="/index/?page={{ posts.next_page_number }}">下一页</a>
    25         {% endif %}
    26     </div>
    27 </body>
    28 </html>
    View Code

      django 的自带分页的弊端是只有上下页可以方便的直接使用,但是如果要显示页码的话,django是全部显示的,这要如果数据量大的话,全端会极其不美观,也不便利,但是如果想让其有固定的页面显示长度,就需要二次开发。 

      Django自定义分页:

      url的custom:

    url(r'^custom/',views.custom)

      在前端的展示样例:

     1 <!DOCTYPE html>
     2 <html lang="en">
     3 <head>
     4     <meta charset="UTF-8">
     5     <title></title>
     6     <link rel="stylesheet" href="/static/plugins/bootstrap-3.3.7-dist/css/bootstrap.css" />
     7 </head>
     8 <body>
     9     <h1>用户列表</h1>
    10     <ul>
    11         {% for row in user_list %}
    12             <li>{{ row.name }}</li>
    13         {% endfor %}
    14     </ul>
    15 
    16     <nav aria-label="Page navigation">
    17       <ul class="pagination">
    18           {{ page_info.pager|safe }}
    19       </ul>
    20     </nav>
    21 </body>
    22 </html>
    View Code

      最为关键的,创建一个utils包,作为模块使用,文件名为pager.py 

     1 class PageInfo(object):
     2 
     3     def __init__(self,current_page,all_count,per_page,base_url,show_page=11):
     4         """
     5         :param current_page: 表示用户当期想要访问的页码
     6         :param all_count: 数据库总行数
     7         :param per_page: 每页显示个数
     8         :param base_url: 每页显示个数
     9         :param show_page: 总共显示多少页码
    10         :return:
    11         """
    12         try:
    13             # 异常处理,页码出现非数字的,返回第一页
    14             self.current_page = int(current_page)
    15         except Exception as e:
    16             # 返回第一页
    17             self.current_page = 1
    18 
    19         # 每页显示的个数
    20         self.per_page = per_page
    21 
    22         #计算需要的页数,总数据行和每页显示的个数做比例
    23         a,b = divmod(all_count,per_page)
    24         if b:
    25             a = a +1
    26         self.all_pager = a
    27         self.show_page = show_page
    28         self.base_url = base_url
    29     def start(self):
    30         #每页的起始的数据行
    31         return (self.current_page-1) * self.per_page
    32 
    33     def end(self):
    34         #每页的结束数据行
    35         return self.current_page * self.per_page
    36 
    37     def pager(self):
    38         # v = "<a href='/custom.html?page=1'>1</a><a href='/custom.html?page=2'>2</a>"
    39         # return v
    40         page_list = []
    41 
    42         #在页码中取一半
    43         half = int((self.show_page-1)/2)
    44 
    45         # 如果数据总页数 < 11
    46         if self.all_pager < self.show_page:
    47             begin = 1
    48             stop = self.all_pager + 1
    49         # 如果数据总页数 > 11
    50         else:
    51             # 如果当前页 <=5,永远显示1,11
    52             if self.current_page <= half:
    53                 begin = 1
    54                 stop = self.show_page + 1
    55             else:
    56                 if self.current_page + half > self.all_pager:
    57                     begin = self.all_pager - self.show_page + 1
    58                     stop = self.all_pager + 1
    59                 else:
    60                     begin = self.current_page - half
    61                     stop = self.current_page + half + 1
    62 
    63         if self.current_page <= 1:
    64             prev = "<li><a href='#'>上一页</a></li>"
    65         else:
    66             prev = "<li><a href='%s?page=%s'>上一页</a></li>" %(self.base_url,self.current_page-1,)
    67         page_list.append(prev)
    68 
    69         for i in range(begin,stop):
    70             if i == self.current_page:
    71                 #class标签是将当前页加标志色
    72                 temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
    73             else:
    74                 temp = "<li><a href='%s?page=%s'>%s</a></li>" %(self.base_url,i,i,)
    75             page_list.append(temp)
    76 
    77         if self.current_page >= self.all_pager:
    78             nex = "<li><a href='#'>下一页</a></li>"
    79         else:
    80             nex = "<li><a href='%s?page=%s'>下一页</a></li>" %(self.base_url,self.current_page+1,)
    81         page_list.append(nex)
    82 
    83         return ''.join(page_list)
    View Code 

      在views中代码实现:在custom函数中,就可以from导入utils模块的pager文件的PageInfole类,直接用,给PageInfo传参即可。

     1 from utils.pager import PageInfo
     2 def custom(request):
     3     #总数据的个数
     4     all_count = models.UserInfo.objects.all().count()
     5     #表示用户当期想要访问的页码
     6     current_page = request.GET.get("page")
     7     # current_page = int(current_page)
     8     #每页显示数据个数
     9     # per_page = 10
    10     # start = (current_page-1) * per_page
    11     # end = current_page * per_page
    12     page_info = PageInfo(current_page,all_count,10,"/index/",11)
    13     # models.UserInfo.objects.all()[起始位置:结束位置]
    14     user_list = models.UserInfo.objects.all()[page_info.start():page_info.end()]
    15 
    16     return render(request,"index.html",{"user_list":user_list,'page_info':page_info})
    View Code

    ------------- END -------------

  • 相关阅读:
    5773. 【NOIP2008模拟】简单数学题
    jzoj_5455. 【NOIP2017提高A组冲刺11.6】拆网线
    5461. 【NOIP2017提高A组冲刺11.8】购物
    博客第三天
    博客第二天
    博客的第一天。
    微服务架构下的session一致性
    分布式数据库数据一致性的原理、与技术实现方案
    epoll的本质
    DNS域名解析过程
  • 原文地址:https://www.cnblogs.com/george92/p/11278364.html
Copyright © 2011-2022 走看看