加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Python > 正文

有局限性分页+斗笔式自定义分页组件

发布时间:2020-12-20 12:54:46 所属栏目:Python 来源:网络整理
导读:利用django自带分页组件实现分页功能 使用分页器Paginator: 在视图中使用 Paginator来为查询集分页。我们提供视图以及相关的模板来展示如何展示这些结果。 Paginator常用属性per_page: 每页显示条目数量count: 数据总个数num_pages:总页数page_range:总页数

利用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(‘‘,22     path(custom/,views.custom),# 自定义分页
23 ]
urls.py

  1 from django.shortcuts import render,HttpResponse
  2 from django.core.paginator import Paginator,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,)
 74             else:
 75                 temp = "<li><a href=‘%s?page=%s‘>%s</a></li>" % (self.base_url,)
 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,/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页)的问题 数据少显示出来的负数页面

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读