首页 > 其他分享 >分页:Paginator

分页:Paginator

时间:2024-08-08 17:51:58浏览次数:7  
标签:Paginator 分页 self list current num 页码 page

提要:列表分页主要是明白:列表当前需要显示内容索引 =(列表当前页数-1)*每页显示条数   至  列表当前页数*每页显示条数

一、Django的内置分页
Django内置的分页需要使用到3个类:Paginator、EmptyPage、PageNotAnInteger

1.1 Paginator介绍
paginator = Paginator(全部数据, 每页显示条数)

paginator对象下面包括属性per_page、count、num_pages、page对象;

page对象下面包括属性:

has_next、next_page_number、has_previous、previous_page_number、number、object_list、paginator对象

下图为各个对象属性的关系及注释:

1.2  EmptyPage、PageNotAnInteger介绍
EmptyPage、PageNotAnInteger这两个类是为了防止p值(当前页码)不是int类型、或者大于总页码的情况;

1.3  简单截取实例
下面简单截取部分代码诠释:

……
from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
def……下面为函数的函数体:
#数据库数据
stu_list=models.Student.objects.all()
cls_list=models.Classes.objects.all()
 
#分页
current_page = request.GET.get('p') 
 #从请求连接中get参数中获取p值,即:当前页码;
所以分页的请求需包含p参数,如:href="/students?p={{ posts.previous_page_number }}"
current_page = int(current_page)
#
paginator = Paginator(stu_list, 10)
        # 全部数据
        # per_page:每页显示条目数量
        # count:数据总个数
        # num_pages:总页数
        # page_range:总页数的索引范围
        # page:page对象(封装了几个属性:是否具有下一页;是否具有上一页;以及下一页/下一页的页码)
try:
    #page对象
    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)
 
 
#pages对象包含了全部的分页需要使用到的属性,包括paginator对象,所以只需将其传入html文件即可;
return render(request,"students.html",{"cls_list":cls_list,"posts":posts})

html文件:

在对应html下include导入pager.html,页面显示:

二、扩展Django内置分页
2.1 继承Paginator类
扩展Django内置分页,主要继承Paginator类,传入参数:current_page(当前页码)、per_pager_num(自定制每页显示页码个数);

之后在对应函数中实例化就只需调用子类CustomerPaginator,传入4个参数:current_page、per_pager_num、全部数据、每页显示条数;

from django.core.paginator import Paginator,EmptyPage,PageNotAnInteger
 
class CustomerPaginator(Paginator):
    '''
    继承Paginator类,用于保留原有功能、并扩展新的功能
    '''
    def __init__(self,current_page,per_pager_num,*args,**kwargs):
        super(CustomerPaginator,self).__init__(*args,**kwargs)
        self.current_page = int(current_page) #当前页码
        self.per_page_num = int(per_pager_num) #分页自定制显示最多页码个数
 
    def pager_num_range(self):
        '''
        CustomerPaginator自定制新功能:显示分页页码
        :return:
        '''
        if self.num_pages < self.per_page_num:
            #当数据的总页码数<自定制的每页显示分页页码数时,显示:1到总页码数
            return range(1,self.num_pages+1)
 
        #自定制每页显示页码数/2,取整,主要是想当前页码显示在页码中央:
        part = int(self.per_page_num/2)
 
        if self.current_page <= part:
            #如果当前页码小于自定制每页显示页码数的一半
            return range(1, self.per_page_num + 1)
 
        if self.current_page + part > self.num_pages:
            # 如果当前页码加上自定制每页显示页码数的一半,大于总页码数:
            return range(self.num_pages - self.per_page_num + 1,self.num_pages + 1)
        #在上面的极端值情况后,常规情况是取当前页前后-+part范围
        return range(self.current_page - part, self.current_page + part + 1)
 
def students(request):
    '''
    学生页面
    :param request:
    :return:
    '''
    stu_list=models.Student.objects.all()
    cls_list=models.Classes.objects.all()
    #分页
    current_page = request.GET.get('p')
    current_page = int(current_page)
    #    
#由于上面使用CustomerPaginator继承了Paginator,所以这里使用CustomerPaginator实例化,传入4个参数:当前页码、每页显示页码个数、全部数据、每页显示数据条数
    paginator = CustomerPaginator(current_page,11,stu_list, 10)
 
    try:
        #page对象
        posts = paginator.page(current_page)
    except PageNotAnInteger:
        posts = paginator.page(1)
    except EmptyPage:
        posts = paginator.page(paginator.num_pages)
 
 
    return render(request,"students.html",{"cls_list":cls_list,"posts":posts})

2.2 前端HTML调用

<ul class="pagination" style="margin-top: 0px">
  <li> <a href="/students.html?p=1" aria-label="F">
            <span aria-hidden="true">首页</span>
          </a></li>
  {% if posts.has_previous %}
         <li> <a href="/students.html?p={{ posts.previous_page_number }}" aria-label="Previous">
            <span aria-hidden="true">上一页</span>
          </a></li>
      {% else %}
          <li> <a href="#" aria-label="Previous">
              <span aria-hidden="true">上一页</span></a>
          </li>
  {% endif %}
  {% for i in posts.paginator.pager_num_range %}
        {% if i == posts.number %}
            <li> <a style="background-color: #9acfea;" href="/students.html?p={{ i }}">{{ i }}</a></li>
        {% else %}
            <li><a href="/students.html?p={{ i }}">{{ i }}</a></li>
        {% endif %}
  {% endfor %}
  {% if posts.has_next %}
          <li><a href="/students.html?p={{ posts.next_page_number }}" aria-label="Next">
            <span aria-hidden="true">下一页</span>
          </a></li>
      {% else %}
       <li><a href="#" aria-label="Next">
            <span aria-hidden="true">下一页</span>
          </a></li>
  {% endif %}
   <li> <a href="/students.html?p={{ posts.paginator.num_pages }}" aria-label="Last">
       <span aria-hidden="true">尾页</span>
   </a></li>
</ul>

三、自定义分页组件
从上面的代码可以看出有两个未解的问题:

1.前端分页的html中的a标签的href链接没有参数化、动态化;还不能百分之百实现别人拿来少部分修改就可以使用;所以,下面自己封装一个类(分页组件);

2.分页类中对象包含了查询的所有数据,万一数据有很多,这样会很浪费性能(针对别的框架哈,django框架不会,因为django是你什么时候需要数据,它才执行)但是还是需要解决;

分页组件代码及部分注释:

 

class Pagination(object):
    '''
    自己封装分页组件,别人拿来就可以使用的,需要条件bootstrap、js、若非bootstrap(如layui)请自行修改标签的class属性
    '''
    def __init__(self,totalCount,currentPage,modelsName,perPageItrmNum= 10,maxPageNum= 7):
        '''
        初始化,传入5个参数
        :param totalCount: 数据总条数
        :param currentPage: 当前页
        :param modelsName: 页码所属模块名,关联url,例举:href='/%s.html?p=%s'%(self.models_name,1)>
        :param perPageItrmNum: 每页显示条数,默认值10
        :param maxPageNum: 最多显示页码个数,默认值7
        '''
        self.total_count=totalCount
        #下面这个对current_page当前页码的初始化使用try,是为了防止current_page不是int类型值或小于1,否则赋值=1
        try:
            pagenum=int(currentPage)
            if pagenum<=0:
                pagenum=1
            self.current_page = pagenum
        except EmptyPage as e:
            self.current_page = 1
        self.models_name=modelsName
        self.per_page_item_num = perPageItrmNum
        self.max_page_num = maxPageNum
 
    @property
    def start(self):
        '''
          需要显示的数据的起始索引
        :return: (当前页-1)* 每页显示条数
        '''
        return (self.current_page-1)*self.per_page_item_num
 
    @property
    def end(self):
        '''
            需要显示的数据的最后索引
        :return:当前页 * 每页显示条数
        '''
        return self.current_page * self.per_page_item_num
 
    @property
    def num_pages(self):
        '''
        总页数
        :return:
        '''
        #divmod(x,y),返回x/y的商a,余数b
        a,b=divmod(self.total_count,self.per_page_item_num)
        if b==0:
            return a
        return a+1
 
    @property
    def pager_num_range(self):
        '''
        Pagination自定制新功能:显示分页页码
        :return:
        '''
        if self.num_pages < self.max_page_num:
            #当数据的总页码数<自定制的每页显示分页页码数时,显示:1到总页码数
            return range(1,self.num_pages+1)
 
        #自定制每页显示页码数/2,取整,主要是想当前页码显示在页码中央:
        part = int(self.max_page_num/2)
 
        if self.current_page <= part:
            #如果当前页码小于自定制每页显示页码数的一半
            return range(1, self.max_page_num + 1)
 
        if self.current_page + part > self.num_pages:
            # 如果当前页码加上自定制每页显示页码数的一半,大于总页码数:
            return range(self.num_pages - self.max_page_num + 1,self.num_pages + 1)
        #在上面的极端值情况后,常规情况是取当前页前后-+part范围
        return range(self.current_page - part, self.current_page + part + 1)
 
    @property
    def page_str_ui(self):
        '''
        将分页html拼接string,前端html直接调用,渲染
        :return:
        '''
        page_list = []
        #ul标签开头
        page_list.append("<ul class='pagination pagination-sm' style='margin-top: 0px'>")
        #首页
        temp_first = "<li> <a href='/%s.html?p=1' aria-label='F'>" \
               "<span aria-hidden='true'>首页</span></a></li>"%(self.models_name)
        page_list.append(temp_first)
        #上一页
        if self.current_page == 1:
            prev="<li> <a href='#'>" \
                 "<span aria-hidden='true'>上一页</span></a></li>"
        else:
            prev="<li> <a href='/%s.html?p=%s'>" \
                 "<span aria-hidden='true'>上一页</span></a></li>"%(self.models_name,self.current_page-1,)
        page_list.append(prev)
 
        #中间页码
        for i in self.pager_num_range:
            if i == self.current_page:
                temp="<li> <a style='background-color: #9acfea;' href='/%s.html?p=%s'>" \
                     "<span aria-hidden='true'>%s</span></a></li>"%(self.models_name,i,i)
            else:
                temp = "<li> <a href='/%s.html?p=%s'>" \
                       "<span aria-hidden='true'>%s</span></a></li>" % (self.models_name, i, i)
            page_list.append(temp)
 
        #下一页
        if self.current_page == self.num_pages:
            nex="<li> <a href='#'>" \
                 "<span aria-hidden='true'>下一页</span></a></li>"
        else:
            nex="<li> <a href='/%s.html?p=%s'>" \
                 "<span aria-hidden='true'>下一页</span></a></li>"%(self.models_name,self.current_page+1,)
        page_list.append(nex)
 
        #尾页
        temp_last = "<li> <a href='/%s.html?p=%s' aria-label='L'>" \
               "<span aria-hidden='true'>尾页</span></a></li>"%(self.models_name,self.num_pages)
        page_list.append(temp_last)
 
        #ul结尾
        page_list.append("</ul>")
 
        return "".join(page_list)

使用该分页组件实例截图:

显示结果截图:

 

标签:Paginator,分页,self,list,current,num,页码,page
From: https://www.cnblogs.com/zycai/p/18349418

相关文章

  • 【YashanDB数据库】Mybatis-plus分页框架识别不到Yashandb
    问题描述Mybatis-plus无法识别Yashandb数据库,应用有如下报错。问题分析从Mybatis-plus源码里面看到,getDBtype函数是没有Yashandb的方言。当Yashandb使用mybatis-plus分页时候,会抛出异常即otherdatabasenotsupported。packagecom.baomidou.mybatisplus.extension.toolkit......
  • 由于分页,无法使用 python al beautifulsoup 在 tripadvisor 中获取所有结果
    我正在尝试获取餐厅的链接,但我只能获取前30家餐厅的链接,而无法获取所有其他餐厅的链接。马德里地区的餐馆有数百家,分页每页只显示30家,以下代码只获取这30家importreimportrequestsfromopenpyxlimportWorkbookfrombs4importBeautifulSoupasbcity_name='......
  • 织梦列表页分页错位(分页显示为竖排)怎么办
    <divclass="dede_pages"><ulclass="pagelist">{dede:pagelistlistitem="info,index,end,pre,next,pageno,option"listsize="5"/}</ul></DIV>css样式代码.dede_pages{text-align:right;}.ded......
  • MyBatis-Pager: 一个轻量且优雅的 MyBatis 分页组件
    优点无侵入:仅需在mapper层接口中增加Pager<T>参数即可。零配置:无需额外增加配置项,能够自动推断数据库分页方言。使用方法SpringBoot2项目引入maven依赖<dependency><groupId>cn.codest</groupId><artifactId>mybatis-pager-spring-boot2-starter</art......
  • [python][代码]Python分页工具类
    这段Python代码定义了一个名为Pagination的类,用于实现数据的分页功能。下面是代码的逐行解释:#encoding:utf-8:指定文件的编码格式为UTF-8。importmath:导入Python的数学模块,用于访问数学函数和常量。定义了Pagination类,它继承自object(在Python3中,所有类都隐式地继承自......
  • mysql数据库查询时用到的分页方法有哪些
     在处理数据库查询时,我们经常需要对结果进行分页,以便在用户界面上提供更好的浏览体验。MySQL提供了几种不同的方法来实现这一功能,其中最常见的是使用LIMIT子句。以下是三种使用LIMIT进行分页的基本方法。一、使用LIMIT子句LIMIT子句用于指定查询结果的最大记录数。它的基本语......
  • mybatis-plus 自定义sql拼接 的方式进行Wrapper条件查询 实现了分页 多表查询
    法一:用单表的思想(可以跳过,直接看法二)方法:先收集公共字段到集合中,再批量查询,然后封装起来缺点:相较于法二,代码量大,多访问了一次数据库service层:@Service@RequiredArgsConstructorpublicclassProductServiceImplextendsServiceImpl<ProductMapper,Product>implements......
  • 第19章 分页机制和动态页面分配
    本章学习目标了解页目录、页表的结构和作用清楚为什么当我们访问一个段的某单元时,处理器能准确的知道它在哪个页,以及页内位置的基本原理1.分页机制概述。1.1简单的分页模型分段的内存管理模式依靠的是段部件。段地址加上偏移量就是线性地址,分页模式没有开启的时候这就......
  • 做Spring Boot图书后台管理项目遇到分页报错的问题
    一、问题    实现分页功能时,点击第几页或者下一页时报错404二、分析问题   1、 使用的是MyBatisPlus框架,实现分页功能需要拦截器,可能是没有添加拦截器。检查是否添加配置类并添加拦截器PageConfiguration配置类/***配置类,用于SpringBoot项目......
  • MyBatisPlus分页查询
     一、导入依赖<!--MyBatis-plus的依赖--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.4</version></dependency><!--mysql的依赖--&......