我的博客从创建之初就有分页,但是只是很简单的显示“上一页 1/20 下一页”这种效果,周末在家优化博客的时候突然奇想完善了一下网站的分页,直接一比一还原了百度搜索页面的分页效果。
其实很多Django网站都分享了关于分页的实现,基本原理是大同小异的,主要是看各自的喜好。其实很多常用的功能只要有参考的模板,基本都是可以自己现实出来的,我的分页效果就是觉得百度这个分页效果还是不错的,所以连bootstrap自带的分页组件都没用,直接就一比一还原百度的效果。
首先看一下百度的分页效果,我截图了几种不同情况的分页效果,这些效果都是需要在设计分页的时候考虑到的。
首先我们需要定义几个概念:
我们分析一下百度的分页在不同场景对应的处理:
经过分页,在忽略页面效果的前提下,我们要实现一个分页效果最关键点就是得到一个要显示的页码列表。
在Django里面可以定义一个标签函数来做分页,这个标签函数的主要目的就是输出要显示的页码列表,然后定义一个分页模板来渲染html页面即可。
定义标签函数
只要是视图继承,我定义的这个分页标签函数都是可以直接使用的,如果是自己定义的分页器,只需要修改标签函数的参数,拿到分页总数和当前页码也可以通用。
这里定义了一个名为的标签函数,使用了Django的模板标签库来注册这个函数作为一个模板标签。
该函数接受两个参数:和。参数是一个上下文对象,包含了模板渲染时的环境变量和变量值。参数是可选的,用于指定最多显示的页面按钮数量,默认值是10。
函数的逻辑是根据传入的中的分页信息来生成适当的页面按钮范围。如果分页总数不大于最大显示数,则直接显示所有页码。如果总页码大于最大显示数,函数会保证当前页码在中间,同时保证能显示最多指定数量的页码。最后,将生成的页码范围存入中,并返回对象。
由于我的所有使用到分页功能的地方都是使用的内置的列表视图类,所以上下文中都是包含分页对象还有当前页对象的,所以可以直接从上下文中拿到,然后就是输出一个显示页的可迭代对象添加到上下文中,以便在模板里面循环迭代。
我的这个标签函数的思路就很简单,我只需要关注最左边和最右边的页码是多少就行,然后只需要保证几个原则就行:第一,最左边最小值为1,第二最右边最大值为总页码数,第三,除非总页码数少于要显示的页码数,不然必须显示规定的长度。
分页模板
经过标签函数我们可以得到要显示的页码列表,同时上下文也是直接继承的,这时候可以定义一个分页模板。
我这个分页模板很容易理解,就是判断有没有上一页和下一页去显示上下页按钮,然后中间的页码直接去循环页码列表。
我这里使用的到了另一个标签函数来处理得到每个页码的跳转地址,而不是像我看到的所有讲Django分页的做法直接使用这个死板的写法,因为我的页面本身就是可能带参数的,比如这种格式,如果还是用就会导致设置不生效,所以我这里定义了一个标签函数来处理当前的地址,大概用途就是只替换链接中的分页参数,比如这里是,这个参数也是可以根据实际来设置的。
我的标签函数如下:
使用分页模板
在任何有分页对象的页面(也就是视图继承自)直接倒入标签函数即可
这里可以随意定义最大显示的页码个数,比如我上面的设置是区分来PC端和移动端,PC端显示10个页码,移动端只显示4个页面。
设置样式
得到分页的基本html之后就是设置css样式就行,设置样式这里就不做描述,毕竟拿着百度的页码抄也能抄成一模一样。
这篇博客主要介绍了作者如何在Django网站中实现了一个类似百度搜索页面的分页效果,并提供了相关代码和思路。
具体的效果这里就不用截图了,直接看我博客效果就行,PC端和移动端的显示长度是不通的,而且基本就是一比一还原了百度的
可以查看我关于分页效果的重构代码提交