zoukankan      html  css  js  c++  java
  • 有局限性分页+斗笔式自定义分页组件

    利用django自带分页组件实现分页功能

    使用分页器Paginator:

    在视图中使用 Paginator来为查询集分页。我们提供视图以及相关的模板来展示如何展示这些结果。

    Paginator常用属性
    per_page: 每页显示条目数量
    count: 数据总个数
    num_pages:总页数
    page_range:总页数的索引范围,页码的范围,从1开始,例如[1, 2, 3, 4]  

    Paginator所需参数:

    object_list 一个列表,元祖或则Django 的Queryset 对象 或其他对象带有 count() or __len__()的方法
    per_page :就是1页显示几条数据  

    Paginator对象的方法:

    page(number) :返回在提供的下标处的Page对象,下标以1开始

    使用page对象方法:

    Page.has_next()
    如果有下一页,则返回True
     
    Page.has_previous()
    如果有上一页,返回 True
     
    Page.has_other_pages()
    如果有上一页或下一页,返回True
     
    Page.next_page_number()
    返回下一页的页码。如果下一页不存在,抛出InvalidPage异常
     
    Page.previous_page_number()
    返回上一页的页码。如果上一页不存在,抛出InvalidPage异常
     
    Page.start_index()
    返回当前页上的第一个对象,相对于分页列表的所有对象的序号,从1开始。比如,将五个对象的列表分为每页两个对象,第二页的start_index()会返回3
     
    Page.end_index()
    返回当前页上的最后一个对象,相对于分页列表的所有对象的序号,从1开始。 比如,将五个对象的列表分为每页两个对象,第二页的end_index() 会返回 4
    

     属性

    Page.object_list
    当前页上所有对象的列表
     
    Page.number
    当前页的序号,从1开始
     
    Page.paginator
    相关的Paginator对象。

    自带分页功能代码

     1 """fbv_cbv URL Configuration
     2 
     3 The `urlpatterns` list routes URLs to views. For more information please see:
     4     https://docs.djangoproject.com/en/2.1/topics/http/urls/
     5 Examples:
     6 Function views
     7     1. Add an import:  from my_app import views
     8     2. Add a URL to urlpatterns:  path('', views.home, name='home')
     9 Class-based views
    10     1. Add an import:  from other_app.views import Home
    11     2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    12 Including another URLconf
    13     1. Import the include() function: from django.urls import include, path
    14     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    15 """
    16 from django.contrib import admin
    17 from django.urls import path, re_path
    18 from app01 import views
    19 
    20 urlpatterns = [
    21     path('admin/', admin.site.urls),
    22     path('index/', views.index),  # 自带分页
    23 ]
    urls.py
     1 from django.db import models
     2 
     3 
     4 class UserType(models.Model):
     5     title = models.CharField(max_length=32)
     6 
     7 
     8 class UserInfo(models.Model):
     9     username = models.CharField(max_length=32)
    10     password = models.CharField(max_length=64)
    11     age = models.IntegerField()
    12     ut = models.ForeignKey('UserType', on_delete=models.CASCADE)
    13 
    14     def __str__(self):
    15         return '%s--%s' % (self.id, self.username)
    models.py
     1 from django.shortcuts import render, HttpResponse
     2 from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage
     3 from app01 import models
     4 
     5 
     6 def index(request):
     7     """
     8     Django自带的分页功能 局限性:不能在其他框架中用  而且只能做到上一页 下一页的位置
     9     :param request:
    10     :return:
    11     """
    12 
    13     # for i in range(300):
    14     #     username = "root" + str(i)
    15     #     models.UserInfo.objects.create(username=username, age=18, ut_id=1)
    16     current_page = request.GET.get('page')
    17     user_list = models.UserInfo.objects.all()
    18     paginator = Paginator(user_list, 10)
    19     # per_page: 每页显示条目数量10
    20     # count:    数据总个数
    21     # num_pages:总页数
    22     # page_range:总页数的索引范围,如: (1,10),(1,200)
    23     # page:     page对象
    24     try:
    25         posts = paginator.page(current_page)
    26     except PageNotAnInteger as e:
    27         posts = paginator.page(1)
    28     except EmptyPage as e:  # 传入负数异常
    29         posts = paginator.page(1)
    30     # has_next              是否有下一页
    31     # next_page_number      下一页页码
    32     # has_previous          是否有上一页
    33     # previous_page_number  上一页页码
    34     # object_list           分页之后的数据列表
    35     # number                当前页
    36     # paginator             paginator对象
    37     return render(request, 'index.html', {"posts": posts})
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <h2>用户列表数据</h2>
        <ul>
            {% for row in posts.object_list  %}
                <li>{{ row.username  }}</li>
            {% endfor %}
        </ul>
        <div>
            {% if posts.has_previous %}
                <a href="?page={{ posts.previous_page_number }}">上一页</a>
            {% endif %}
    
            {% for num in posts.paginator.page_range %}
                <a href="?page={{ num }}">{{ num }}</a>
            {% endfor %}
            
            {% if posts.has_next %}
                <a href="?page={{ posts.next_page_number }}">下一页</a>
            {% endif %}
        </div>
    </body>
    </html>

    自带分页实现的效果

      

    总结下自带的分页:1.局限性太强,不能在其它框架中用2.只能做到上一页下一页位置3.如果数据库数据非常多,页码全部展示在一个页面肯定是不好的

    自定义分页功能

    实现主要思想:1.创建一个类,封装用户传递的页码、统计数据库总的个数、每页显示的数据条数、展示的页码数量、基本的url路径

           2.在类中实现当前页面的起始位置数据

           3.在页面上展示的页码条数以及上页下页(处理上页下页逻辑多做出判断) 

     1 """fbv_cbv URL Configuration
     2 
     3 The `urlpatterns` list routes URLs to views. For more information please see:
     4     https://docs.djangoproject.com/en/2.1/topics/http/urls/
     5 Examples:
     6 Function views
     7     1. Add an import:  from my_app import views
     8     2. Add a URL to urlpatterns:  path('', views.home, name='home')
     9 Class-based views
    10     1. Add an import:  from other_app.views import Home
    11     2. Add a URL to urlpatterns:  path('', Home.as_view(), name='home')
    12 Including another URLconf
    13     1. Import the include() function: from django.urls import include, path
    14     2. Add a URL to urlpatterns:  path('blog/', include('blog.urls'))
    15 """
    16 from django.contrib import admin
    17 from django.urls import path, re_path
    18 from app01 import views
    19 
    20 urlpatterns = [
    21     path('admin/', admin.site.urls),
    22     path('custom/', views.custom),  # 自定义分页
    23 ]
    urls.py
      1 from django.shortcuts import render, HttpResponse
      2 from django.core.paginator import Paginator, Page, PageNotAnInteger, EmptyPage
      3 from app01 import models
      4 
      5 
      6 class PageInfo(object):
      7     def __init__(self, current_page, all_count, per_page, base_url, show_page=11):
      8         """
      9 
     10         :param current_page: 当前用户传递的页码
     11         :param all_count:    数据库总的多少条个数
     12         :param per_page:     每页显示的数据条数
     13         :param show_page:    看到页码的最大值  前5条加后5条+当前页
     14         :param base_url:     url路径
     15         """
     16         try:
     17             self.current_page = int(current_page)
     18         except Exception as e:
     19             self.current_page = 1
     20         self.per_page = per_page
     21 
     22         a, b = divmod(all_count, per_page)
     23         if b:
     24             a = a + 1
     25         self.all_pager = a
     26         self.show_page = show_page
     27         self.base_url = base_url
     28 
     29     def start(self):
     30         return (self.current_page-1)*self.per_page
     31 
     32     def end(self):
     33         return self.current_page*self.per_page
     34 
     35     def pager(self):
     36         # v = "<a href='/custom/?page=6'>6</a>"
     37         # return v
     38         page_list = []
     39         # 调整起始位置就可以在当前页码前几个显示出来后几页显示出来
     40         harf = int((self.show_page-1)/2)  # 5
     41         # begin = self.current_page - harf
     42         # stop = self.current_page + harf + 1
     43 # 判断起始 结束  加中间页码的逻辑
     44         # 如果数据总页数小于11(默认页码显示的最大值)
     45         if self.all_pager < self.show_page:
     46             begin = 1
     47             stop = self.all_pager + 1
     48         # 如果数据总页数大于11(默认页码显示的最大值)
     49         else:
     50             # 如果当前页<=5  就永远显示1,11页
     51             if self.current_page <= harf:
     52                 begin = 1
     53                 stop = self.show_page + 1
     54             else:
     55                 # 这里注意  如果后边没数据浏览的页码大于全部页码时候也要进行处理
     56                 if self.current_page + harf > 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 - harf
     61                     stop = self.current_page + harf + 1
     62 
     63         # begin = self.current_page - 5
     64         # stop = self.current_page + 5 + 1
     65         if self.current_page <= 1:
     66             prev = "<li><a href='#'>上一页</a></li>"
     67         else:
     68             prev = "<li><a href='%s?page=%s'>上一页</a></li>" % (self.base_url, self.current_page - 1)
     69         page_list.append(prev)
     70 
     71         for i in range(begin, stop):
     72             if i == self.current_page:
     73                 temp = "<li class='active'><a href='%s?page=%s'>%s</a></li>" % (self.base_url, i, i,)
     74             else:
     75                 temp = "<li><a href='%s?page=%s'>%s</a></li>" % (self.base_url, i, i,)
     76             page_list.append(temp)
     77 
     78         if self.current_page >= self.all_pager:
     79             nex = "<li><a href='#'>下一页</a></li>"
     80         else:
     81             nex = "<li><a href='%s?page=%s'>下一页</a></li>" % (self.base_url, self.current_page + 1)
     82         page_list.append(nex)
     83 
     84         return ''.join(page_list)
     85 
     86 
     87 def custom(request):
     88     """
     89     自定义分页
     90     :param request:
     91     :return:
     92     """
     93     # 假设当前页为第5页
     94     current_page = request.GET.get('page')
     95     all_count = models.UserInfo.objects.all().count()
     96     # current_page = int(current_page)
     97     # 每页显示的数据个数
     98     per_page = 10
     99     # 1   [0  10]
    100     # 2   [10  20]
    101     # 3   [20  30]
    102     page_info = PageInfo(current_page, all_count, per_page, '/custom/', 11)
    103     # start = (current_page-1)*per_page
    104     # end = current_page*per_page
    105     # user_list = models.UserInfo.objects.all()[开始位置:结束位置]
    106     user_list = models.UserInfo.objects.all()[page_info.start(): page_info.end()]
    107 
    108     return render(request, "custom.html", {"user_list": user_list, "page_info": page_info})
    views.py
    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title></title>
        <link rel="stylesheet" href="/static/bootstrap-3.3.7-dist/css/bootstrap.css">
    </head>
    <body>
        <h2>用户列表数据</h2>
        <ul>
            {% for row in user_list  %}
                <li>{{ row.username  }}</li>
            {% endfor %}
        </ul>
    
        <nav aria-label="Page navigation">
        <ul class="pagination">
               {{ page_info.pager | safe }}
        </ul>
    </nav>
    </body>
    </html>
    

     静态文件的加载就不上传了  下载下来用就是了 

     自带分页器+自定义分页目录

     

            数据少时,大于总页数就没数据了的处理  处理默认显示的总的页码(11页)的问题 数据少显示出来的负数页面

  • 相关阅读:
    .NET面试题解析(07)-多线程编程与线程同步
    .NET面试题解析(06)-GC与内存管理
    .NET面试题解析(05)-常量、字段、属性、特性与委托
    .NET面试题解析(04)-类型、方法与继承
    .NET面试题解析(03)-string与字符串操作
    .NET面试题解析(02)-拆箱与装箱
    .NET面试题解析(01)-值类型与引用类型
    StackExchange.Redis使用配置
    X--名称空间详解
    深入浅出话资源
  • 原文地址:https://www.cnblogs.com/Alexephor/p/11258250.html
Copyright © 2011-2022 走看看