最近项目中有需求使用到了分页,由于项目是使用的Django,所以也就使用了Django的Paginator类,简单记录下
可以使用一个小的Django项目来进行测验,具体的准备(创建项目,创建app,配置数据库,app中定义模型等等...工作就不多说了,百度一下就有很详细的教程。
1)首先应该了解Paginato类和它的实例对象的一些熟悉。
Paginator类实例对象
- 方法_init_(列表,int):返回分页对象,第一个参数为列表数据,第二个参数为每页数据的条数。
- 属性count:返回对象总数。
- 属性num_pages:返回页面总数。
- 属性page_range:返回页码列表,从1开始,例如[1, 2, 3, 4]。
- 方法page(m):返回Page类实例对象,表示第m页的数据,下标以1开始。
Page类实例对象
- paginator =Paginator(数据库数据,一页显示多少条) 实例化对象
- obj = paginator.page(页码)当前页的数据
- obj.paginator:当前页对应的Paginator对象。
- obj.object_list QuerySet,当前页对象查询集
- obj.has_previous() 是否有上一页
- obj.previous_page_num上一页页码
- obj.has_next() 是否有下一页
- obj.number 返回当前是第几页,从1开始
其它还有很多,如果使用IDE是pycham,输入“obj.”会有很多属性
所以利用Django的Paginator思路可以是:
1)定义视图函数test_paginator(request,页码)
这个视图函数的名称随便取
2)从数据库中查询数据
3)使用Paginator类对获取的数据进行实例化
paginator =Paginator(对象,一页显示数据)
4)通过实例化对象paginator的page()方法获取当页的数据,括号里面是页码数
obj = paginator.page(页码)
5)把得到的obj返回前端
6)在前端通过obj.object_list 获取获取当前页的数据,对获取的遍历,然后通过“.属性”的方法获取需要的值并显示在前端页面
7)以上只是显示当前页的数据,接下来是页码的显示以及点击页码数跳转到页码并显示数据。
在前端利用obj.page_range获取页码列表,然后遍历列表,获取页码,写个a标签,href的值是带页码参数的链接,也就是访问第一步的视图函数,至于urls,使用\d+正则接收变动的页码参数就行。
个人认为思路比代码重要,所以就没写demo栗子,实际代码又在项目中,不方便拿出来,有不懂的,可以留言~
============================更新于2018-3.29=====================================
最近又发现了一个新方法,后端对Django的分页进行封装,以下是封装函数
def paginator(data_list, per_page, page_no):
"""
功能说明 封装Django自带的分页函数
接收三个值:需要分页的对象,每页多少条数据,需要返回的页码
返回三个值:分页后的对象,需要返回的页码,分页信息
"""
data = Struct()
from django.core.paginator import Paginator
pages = Paginator(data_list, per_page)
# 防止超出页数
if not page_no > 0:
page_no = 1
if page_no > pages.num_pages:
page_no = pages.num_pages
p = pages.page(page_no)
data.count = pages.count
data.page_num = pages.num_pages
data.per_page = per_page
data.current = page_no
data.start_index = p.start_index() - 1
return p.object_list, page_no, data
关于data = Struct()封装:
class Struct(dict):
"""
- 为字典加上点语法. 例如:
>>> o = Struct({'a':1})
>>> o.a
>>> 1
>>> o.b
>>> None
"""
def __init__(self, dictobj={}):
self.update(dictobj)
def __getattr__(self, name):
# Pickle is trying to get state from your object, and dict doesn't implement it.
# Your __getattr__ is being called with "__getstate__" to find that magic method,
# and returning None instead of raising AttributeError as it should.
if name.startswith('__'):
raise AttributeError
return self.get(name)
def __setattr__(self, name, val):
self[name] = val
def __hash__(self):
return id(self)
调用的时候:
page, page_no, data.pages = paginator(users, 15, page_no)
前端分页可以使用js:
<script>
var pages = {}
pages.page_num = "{{pages.page_num}}";
pages.curr = "{{pages.current}}";
$(function () {
iniPage(pages.page_num, pages.curr)
})
function iniPage(page_num, curr) {
laypage({
cont: 'page', //容器。值支持id名、原生dom对象,jquery对象。【如该容器为】:<div id="page1"></div>
pages: page_num, //通过后台拿到的总页数
curr: curr, //当前页
groups: 10, // 显示多少组分页,10分页下标显示效果就是1-10...最后一页。15分页下标显示效果就是1-15...最后一页,
first: 1,
last: page_num,
skin: '#65cea7',
jump: function(obj, first){ //触发分页后的回调
if(!first) {
search(obj.curr)
}
}
});
}
效果:
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsICM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TPn5UNNRlTzEFRNBDOsJGcohVYsR2MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DOzYzMxATMwETOyMDM4EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
或者layui-js:
<script>
// 分页信息
page_no = {{ pages.current }};
layui.use(['laypage'], function () {
pages = layui.laypage.render({
elem: $("#page"), //容器。值支持id名、原生dom对象,jquery对象。【如该容器为】:<div id="page1"></div>
count: {{ pages.count }}, // 总数
limit: {{pages.per_page}}, // 每页数量
curr: {{pages.current}}, // 当前页
groups: 10,
first: 1,
last: {{pages.page_num}},
theme: '#65cea7',
layout: ['count', 'prev', 'page', 'next'],
jump: function (obj, first) { //触发分页后的回调
if (!first) {
search(obj.curr)
}
}
});
})
</script>
效果: