1 分页类
utils.pageinfo.py
class PageInfo(object):
"""
通用分页类
"""
def __init__(self, curent_page, total_page, show_page_nums, per_page_number, url_prefix):
"""
curent_page : 当前请求页,来自于url,>0的int类型
total_page :总页数 int类型
show_page_nums : 显示在画面中的页码 int类型
per_page_number : 每页显示的条目数
"""
if isinstance(curent_page, int) and curent_page >= 1:
self.curent_page = curent_page
else:
self.curent_page = 1
self.total_page = total_page
self.show_page_nums = show_page_nums
self.per_page_number = per_page_number
self.url_prefix = url_prefix
# self.half 存储页码范围
self.half = int(show_page_nums / 2)
@property
def start(self):
return (self.curent_page - 1) * self.per_page_number
@property
def end(self):
return self.curent_page * self.per_page_number
def pagestr(self):
page_info_list = []
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page=1">首页</a>')
if self.curent_page <= 1:
page_info_list.append(f'<a class="pageNum" href="#">上一页</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.curent_page - 1}">上一页</a>')
# 如果数据总页数小于展示的页数,那么页数就从第一页~总页数
if self.total_page <= self.show_page_nums:
for i in range(1, self.total_page + 1):
if i == self.curent_page:
page_info_list.append(f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
else:
# 如果我们想显示11个页码,那么当前页的前后应该各有5条数据,为了保证当前页前面的页码不出现0或者负数,
# 所以页码范围从1一直到需要显示到11
if self.curent_page - self.half <= 0:
for i in range(1, self.show_page_nums + 1):
if i == self.curent_page:
page_info_list.append(f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
else:
# 如果当前页码加上后面的页数超过了总页数,同页显示总页数前面的十条数据
if self.curent_page + self.half >= self.total_page:
for i in range(self.total_page - self.show_page_nums + 1, self.total_page + 1):
if i == self.curent_page:
page_info_list.append(
f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
else:
# 如果不是上面两种极限情况,就按照正常的数据前后各5页数据执行
for i in range(self.curent_page - self.half, self.curent_page + self.half + 1):
if i == self.curent_page:
page_info_list.append(
f'<a class="pageNum active" href="{self.url_prefix}?page={i}">{i}</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={i}">{i}</a>')
if self.curent_page >= self.total_page:
page_info_list.append(f'<a class="pageNum" href="#">下一页</a>')
else:
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.curent_page + 1}">下一页</a>')
page_info_list.append(f'<a class="pageNum" href="{self.url_prefix}?page={self.total_page}">尾页</a>')
return ''.join(page_info_list)
2 django实际应用案例
2.1 视图函数
views.py
def test(requset):
# 获取page_number 数据
try:
if int(requset.GET.get("page", 1)) > 0:
page_number = int(requset.GET.get("page", 1))
else:
page_number = 1
except Exception:
page_number = 1
# 表内的数据条数
item_count = TestTable.objects.all().count()
# 每页显示的数据条目数
per_page_number = 10
# 总页数需要多少页,不足一页得也需要一页显示
total_page,b = divmod(item_count, per_page_number)
if b:
total_page += 1
# 窗口中显示得页码个数
show_page_nums = 7
# 实例化分页类
page_info_obj = pageinfo.PageInfo(
curent_page = page_number, # 当前请求页
total_page = total_page, # 总页数
show_page_nums = show_page_nums, # 需要显示得页数
per_page_number = per_page_number, # 每页显示得条目数
url_prefix = "/app01/test.html/" # 需要分页得URL
)
tag_list = TestTable.objects.all()[page_info_obj.start: page_info_obj.end] # 获取分页后的列表
return render(requset, 'test.html', {"tag_list":tag_list, "total_page_list":page_info_obj.pagestr()}) # 返回响应
2.2 数据模型
models.py
class TestTable(models.Model):
tid = models.BigIntegerField(primary_key=True)
tname = models.CharField(max_length=30)
表中插入得虚拟数据:
2.3 模板
test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
.pageNum {
display: inline-block;
padding: 5px;
margin: 5px;
text-decoration: none;
}
.active {
background-color: cornflowerblue;
font-weight: bold;
}
.ishidden {
display: none;
}
</style>
</head>
<body>
<h1>变量列表</h1>
<ul>
{% for row in tag_list %}
<li>{{ row.tname }}</li>
{% endfor %}
</ul>
{{ total_page_list | safe }}
</body>
</html>
分页效果
如果需要可以自己加样式,bootstrap等
Update 2022-05-25
解决了分页干扰其他参数的问题
class Pagination(object):
def __init__(self, current_page, all_count, base_url, query_params, per_page=30, pager_page_count=11):
"""
分页初始化
:param current_page: 当前页码
:param per_page: 每页显示数据条数
:param all_count: 数据库中总条数
:param base_url: 基础URL
:param query_params: QueryDict对象,内部含所有当前URL的原条件
:param pager_page_count: 页面上最多显示的页码数量
"""
self.base_url = base_url
try:
self.current_page = int(current_page)
if self.current_page <= 0:
self.current_page = 1
except Exception as e:
self.current_page = 1
query_params = query_params.copy()
query_params._mutable = True
self.query_params = query_params
self.per_page = per_page
self.all_count = all_count
self.pager_page_count = pager_page_count
pager_count, b = divmod(all_count, per_page)
if b != 0:
pager_count += 1
self.pager_count = pager_count
half_pager_page_count = int(pager_page_count / 2)
self.half_pager_page_count = half_pager_page_count
@property
def start(self):
"""
数据获取值起始索引
:return:
"""
return (self.current_page - 1) * self.per_page
@property
def end(self):
"""
数据获取值结束索引
:return:
"""
return self.current_page * self.per_page
def page_html(self):
"""
生成HTML页码
:return:
"""
if self.all_count == 0:
return ""
# 如果数据总页码pager_count<11 pager_page_count
if self.pager_count < self.pager_page_count:
pager_start = 1
pager_end = self.pager_count
else:
# 数据页码已经超过11
# 判断: 如果当前页 <= 5 half_pager_page_count
if self.current_page <= self.half_pager_page_count:
pager_start = 1
pager_end = self.pager_page_count
else:
# 如果: 当前页+5 > 总页码
if (self.current_page + self.half_pager_page_count) > self.pager_count:
pager_end = self.pager_count
pager_start = self.pager_count - self.pager_page_count + 1
else:
pager_start = self.current_page - self.half_pager_page_count
pager_end = self.current_page + self.half_pager_page_count
page_list = []
if self.current_page <= 1:
prev = '<li><a href="#">上一页</a></li>'
else:
self.query_params['page'] = self.current_page - 1
prev = '<li><a href="%s?%s">上一页</a></li>' % (self.base_url, self.query_params.urlencode())
page_list.append(prev)
for i in range(pager_start, pager_end + 1):
self.query_params['page'] = i
if self.current_page == i:
tpl = '<li class="active"><a href="%s?%s">%s</a></li>' % (
self.base_url, self.query_params.urlencode(), i,)
else:
tpl = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.query_params.urlencode(), i,)
page_list.append(tpl)
if self.current_page >= self.pager_count:
nex = '<li><a href="#">下一页</a></li>'
else:
self.query_params['page'] = self.current_page + 1
nex = '<li><a href="%s?%s">下一页</a></li>' % (self.base_url, self.query_params.urlencode(),)
page_list.append(nex)
if self.all_count:
tpl = "<li class='disabled'><a>共%s条数据,页码%s/%s页</a></li>" % (
self.all_count, self.current_page, self.pager_count,)
page_list.append(tpl)
page_str = "".join(page_list)
return page_str