Python——Django框架(九)、Django内置分页组件、分页拓展、自定义分页

Python——Django框架(九)、Django内置分页组件、分页拓展、自定义分页

参考博客:https://www.cnblogs.com/wupeiqi/articles/5246483.html

一、Django自带的分页组件

1、前期准备与URL控制分页

首先是路由这块,re_path 带的正则表达式应该这么写:
在这里插入图片描述
为了以后分页,路由带了数字的前期准备。

然后举个例子:
在这里插入图片描述
结果:
在这里插入图片描述

数量很多很多,这时候就需要分页。

如果在地址栏上这么写:
在这里插入图片描述

意思为看第一页,那么这样:
在这里插入图片描述

可以获取 p 等于几,比如p=1 等于第一页, p=2等于第二页。
假设我们每页显示10条数据,那么:
在这里插入图片描述

接着:
在这里插入图片描述
这样一来,可以通过控制URL来展示对应的数据:
在这里插入图片描述
在这里插入图片描述

2、上一页与下一页

接下来制作按钮,手动控制上一页与下一页

首先是后端:
在这里插入图片描述
然后前端:
在这里插入图片描述
接着就能够实现基本的功能:
在这里插入图片描述

到目前为止,如果只是这种分页的功能,Django内置的分页组件就能够帮我们完成

3、Django自带的分页功能

如果要使用Django内置的分页功能,需要先引入一些东西:
在这里插入图片描述
然后:
在这里插入图片描述
然后前端:
在这里插入图片描述
接着看实现效果:
在这里插入图片描述
然后是上一页与下一页的设置:
在这里插入图片描述

可以看到分页这边写了很多分页代码,可以把这段代码单独保存起来,用的时候直接调用:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
这样代码简洁很多。

4、扩展Django自带的分页组件

在这里插入图片描述
这里已经基本实现了分页与上一页跟下一页的功能了,接下来就是要实现带有数字的分页功能与点击数字调到指定页码。

但是Django自带的分页组件并没有这种功能,所以我们需要自己来实现。但是自己实现新功能,切记不要改源码,源码不能随便改,但是我们可以创建一个类,这个新创建的类可以继承 Paginator 这个类,然后通过这个新加的类来增加新功能。

在这里插入图片描述

然后前端页面显示页码的代码:
在这里插入图片描述
接着效果:
在这里插入图片描述
然后我们点击相对应的代码就能够跳转到相对应的页面。

但是效果还没有做好。我们让当前页面的样式要突出,非当前页面的样式则为普通,可以这么搞:
在这里插入图片描述
然后效果:
在这里插入图片描述
但是页码远不止这么点,而且页码数量不能写死,应该动态生成

由于创建了新类,就不使用原来的Django提供的类,而使用创建的新类:
在这里插入图片描述
然后继续往新类上添加功能(页码的动态生成):
在这里插入图片描述
由于新增了两个参数,所以下面这个地方也要改:
在这里插入图片描述

那么接下来就要计算总页数,如果页数少于11,不可能还显示11页。如果从第一页开始,不可能让第一页居中,以及最后11页同理。以下是相关代码:
在这里插入图片描述
效果图:
前面几页:
在这里插入图片描述

普通情况:

在这里插入图片描述
最后几页:
在这里插入图片描述
那么我们已经写好的这块代码,以后就可以单独保存起来,保存到一个py文件里,以后有需要使用可以直接拿来使用。

二、自定义分页组件

1、小结前面以及分析要做的自定义组件

先来总结下扩展Django的分页功能:
在这里插入图片描述
然后自己要做的:
在这里插入图片描述
可以看到,区别在于这里只需要取出个数即可,可以通过计算,这一次只取多少到多少,然后再根据索引到数据库取数据即可。如果像Django那样直接取出数据,如果数据有一百万条,服务器就直接炸了。

那么为什么Django要这么做呢?
因为Django有个延迟加载,执行完 modle.xxxxx,并没有到数据库取数据,而是什么时候需要取数据才什么时候取。

2、开始自定义分页组件

首先我们创建一个 py 文件,在里面创建一个类,通过这个类来实现我们想要的功能:
在这里插入图片描述
在这里插入图片描述

前端代码:
在这里插入图片描述

然后效果:
在这里插入图片描述
可以看到,数据能出来了,接着制作上一页与下一页,制作之前先把前面已经弄好的代码可以放过来:
在这里插入图片描述
但是我们还少了一些东西,比如总页数,总页数需要计算,所以我们可以再添加计算页数的功能:
在这里插入图片描述
接着前端可以像前面一样:
在这里插入图片描述

虽然效果能够实现,但是这样跟Django自带的效果一样,于是决定换个方式:
在这里插入图片描述

后端代码可以插入一些前端的代码,然后前端直接调用:
在这里插入图片描述

然后结果:
在这里插入图片描述
因为Django的保护,这么用是生成不了的,需要加个 safe :
在这里插入图片描述

然后效果:
在这里插入图片描述
到此,基本就实现了,当然,上一页下一页还没实现:
首先改个地方:
在这里插入图片描述
然后:
在这里插入图片描述
然后效果:
在这里插入图片描述
到此要实现的效果就都实现了。当然我们还可以实现其它效果,比如首页尾页:
在这里插入图片描述

在这里插入图片描述
然后效果:
在这里插入图片描述
然后补充当前页突出显示:
在这里插入图片描述

效果:
在这里插入图片描述
可能会有人觉得不好看,可以自行加样式,调整的更加好看。

3、总结

到此,没有依赖Django的任何东西,就实现了分页的功能。

下面是总代码:

首先先看下 views 层调用的代码:
在这里插入图片描述
然后是前端代码:
在这里插入图片描述
然后是自定义分页功能的代码图:
在这里插入图片描述
在这里插入图片描述
自定义分页功能代码(可复制):

class Pagination(object):
    def __init__(self,totalCount,currentPage,perPageItemNum = 30 , maxPageNum = 7):
        self.totalCount = totalCount        # 数据总个数

        try:        #异常处理,如果用户输入的页码有误,则直接将页码置于1
            v = int(currentPage)     # 当前页
            if v <= 0 :     # 作判断,如果输入例如 -1 这种
                v = 1
            self.current_page = v
        except Exception as e:
            self.current_page = 1

        self.perPageItemNum = perPageItemNum        # 每页显示的行数
        self.maxPageNum = maxPageNum        # 最多显示多少页码

    def start(self):        # 页码对应的起始数据
        return (self.current_page - 1) * self.perPageItemNum

    def end(self):          # 页码对应的结尾数据
        return self.current_page * self.perPageItemNum

    @property       #把方法伪造成属性,如果不加这个,下面用到这个方法都要加括号
    def num_pages(self):
        # 可以用py的内置函数 divmod ,输入被除数与除数,可以得到商跟余数

        a,b = divmod(self.totalCount,self.perPageItemNum)   # a是商,b是余数
        if b == 0:
            return a
        return a+1

    def pager_num_range(self):      #显示页码,这里是1到11
        # 当前页               self.current_page
        # 最多显示的页码数量11   self.perPageItemNum
        # 总页数               self.num_pages
        if self.num_pages < self.maxPageNum:     # 如果总页数少于要显示的11页,则只输出这么点页数
            return range(1,self.num_pages+1)

        part = int(self.maxPageNum/2)        # 取11的中间页码,让当前页码始终处于中间状态,前后都有页码可以点击

        if self.current_page <= part:       #这里处理从第一页开始时,页码的显示情况
            return range(1,self.maxPageNum+1)    # 如果当前页小于6,则显示页码数量为1到11

        if (self.current_page + part) > self.num_pages:     #这里处理页码处于最后的11页的时候
            return range(self.num_pages - self.maxPageNum + 1 , self.num_pages + 1)      #当前页处于最后的11页时,直接显示最后的11页

        return range(self.current_page - part ,self.current_page + part + 1)   # 当前页居中时,前面显示5条页码,后面显示5条页码

    def page_str(self):
        page_list = []

        first = "<a href='/index2.html?p=1' > 首页 </a>"
        page_list.append(first)

        if self.current_page == 1:       # 如果为第一页,则点击上一页无效果
            prev = "<a href='#' > 上一页 </a>"
        else:
            prev = "<a href='/index2.html?p=%s' > 上一页 </a>" %(self.current_page - 1,)
        page_list.append(prev)      #把上一页的标签放到数组中

        for i in self.pager_num_range():
            if i == self.current_page:
                temp = "<a style='font-size:30px;' href='/index2.html?p=%s'> %s </a>" %(i,i)    #动态生成前端标签
            else:
                temp = "<a  href='/index2.html?p=%s'> %s </a>" % (i, i)
            page_list.append(temp)

        if self.current_page == self.num_pages:      # 如果页码为最后一页,则点击下一页无效果
            nex = "<a href='#' > 下一页 </a>"
        else:
            nex = "<a href='/index2.html?p=%s' > 下一页 </a>" %(self.current_page + 1,)
        page_list.append(nex)       #把下一页的标签放到数组中

        last = "<a href='/index2.html?p=%s' > 尾页 </a>" %(self.num_pages,)
        page_list.append(last)

        return ''.join(page_list)

猜你喜欢

转载自blog.csdn.net/qq_41824825/article/details/116210400