143 lines
5.9 KiB
Python
143 lines
5.9 KiB
Python
|
"""
|
|||
|
分页组件,武沛奇视频课件讲解
|
|||
|
"""
|
|||
|
from django.utils.safestring import mark_safe
|
|||
|
|
|||
|
|
|||
|
class Pagination(object):
|
|||
|
def __init__(self, request, queryset, PAGE_SIZE=10, page_param='indexPage', PLUS_NAV=5):
|
|||
|
"""
|
|||
|
:param request: 视图函数,请求的对象
|
|||
|
:param queryset: 传递过来的查询结果集,符合条件的记录
|
|||
|
:param PAGE_SIZE: 每页显示记录数
|
|||
|
:param page_param: 前端传递过来的页码 eg:/list/?indexPage=12
|
|||
|
:param PLUS_NAV: 页码前后各几页
|
|||
|
"""
|
|||
|
# 为解决搜索后,分页导航url地址丢失的问题
|
|||
|
import copy
|
|||
|
# 将url地址中所带的参数复制一份
|
|||
|
query_dict = copy.deepcopy(request.GET)
|
|||
|
# 允许修改
|
|||
|
query_dict._mutable = True
|
|||
|
self.query_dict = query_dict
|
|||
|
|
|||
|
|
|||
|
self.page_param = page_param
|
|||
|
|
|||
|
page = request.GET.get(page_param, '1') # 当前页,默认第1页,如果是跳转的就读indexPage输入框内的值
|
|||
|
if page.isdecimal(): # 判断page是否是一个数字
|
|||
|
page = int(page)
|
|||
|
else:
|
|||
|
page = 1
|
|||
|
self.page = page
|
|||
|
self.page_size = PAGE_SIZE # 每页10条数据
|
|||
|
self.star_page_data = (page - 1) * PAGE_SIZE # 开始数据
|
|||
|
self.end_page_data = page * PAGE_SIZE # 结束数据
|
|||
|
|
|||
|
# star_page_data 开始记录数
|
|||
|
# end_page_data 结束记录数
|
|||
|
# [0:10] 取前10条数据
|
|||
|
self.page_queryset = queryset[self.star_page_data:self.end_page_data]
|
|||
|
|
|||
|
# 统计共有多少条数据
|
|||
|
# total_count_data 总记录数
|
|||
|
total_count_data = queryset.count()
|
|||
|
|
|||
|
# 计算总页数 方法:通过总记录数和每页显示数相除
|
|||
|
# divmod函数是python自带函数,计算两数相除同时获得商和余数,例如 divmod(91,10) 结果等于 {9,1}
|
|||
|
# total_count_page总页数 , mod就是余数
|
|||
|
total_count_page, mod = divmod(total_count_data, PAGE_SIZE)
|
|||
|
if mod:
|
|||
|
total_count_page += 1 # 如果有余数总页数+1
|
|||
|
self.total_count_page = total_count_page
|
|||
|
self.plus_nav = PLUS_NAV
|
|||
|
|
|||
|
# 生成分页导航条
|
|||
|
def html(self):
|
|||
|
"""
|
|||
|
生成分页导航条
|
|||
|
计算出当前页前5页和后5页的页码
|
|||
|
self.plus_nav 前后显示几页
|
|||
|
star_page 起始页
|
|||
|
end_page 结束页
|
|||
|
total_count_page 总页数
|
|||
|
page_nav 导航条的html代码
|
|||
|
|
|||
|
"""
|
|||
|
|
|||
|
# 计算导航栏页码数和显示方式(要考虑翻页时的极值)
|
|||
|
# 效果是前5页和后5页 self.plus_nav
|
|||
|
|
|||
|
# 当数据量少比如只有100条数据以内,则展示全部导航条
|
|||
|
if self.total_count_page <= self.plus_nav * 2:
|
|||
|
star_page = 1
|
|||
|
end_page = self.total_count_page
|
|||
|
else: # 大于100条数据时 显示前后5条数据
|
|||
|
# 如果当前页小于5条(极植)
|
|||
|
if self.page <= self.plus_nav:
|
|||
|
star_page = 1
|
|||
|
end_page = self.plus_nav * 2
|
|||
|
else:
|
|||
|
# 当前是每后一页时(极植)
|
|||
|
if (self.page + self.plus_nav) >= self.total_count_page:
|
|||
|
star_page = self.total_count_page - self.plus_nav * 2 # 显示前10页导航
|
|||
|
end_page = self.total_count_page
|
|||
|
else:
|
|||
|
star_page = self.page - self.plus_nav
|
|||
|
end_page = self.page + self.plus_nav
|
|||
|
|
|||
|
# 生成分页导航条的html代码,并传递给前端
|
|||
|
page_list = []
|
|||
|
|
|||
|
# 首页
|
|||
|
# prev = '<li><a href="?page=1">首页</a></li>'
|
|||
|
# 向url地址中拼接参数
|
|||
|
self.query_dict.setlist(self.page_param, [1])
|
|||
|
# 取得拼接后的url地址self.query_dict.urlencode()
|
|||
|
prev = f'<li><a href="?{self.query_dict.urlencode()}" aria-label="Previous"><span aria-hidden="true">«</span></a></li>'
|
|||
|
page_list.append(prev)
|
|||
|
|
|||
|
# 上一页
|
|||
|
if self.page > 1:
|
|||
|
self.query_dict.setlist(self.page_param, [self.page - 1])
|
|||
|
prev = f'<li><a href="?{self.query_dict.urlencode()}">上一页</a></li>'
|
|||
|
page_list.append(prev)
|
|||
|
|
|||
|
for i in range(star_page, end_page + 1): # range前取后不取所以+1
|
|||
|
self.query_dict.setlist(self.page_param, [i])
|
|||
|
if i == self.page:
|
|||
|
ele = f'<li class="active"><a href="?{self.query_dict.urlencode()}">{i}</a></li>' # 给当前页加效果
|
|||
|
else:
|
|||
|
ele = f'<li><a href="?{self.query_dict.urlencode()}">{i}</a></li>'
|
|||
|
page_list.append(ele)
|
|||
|
|
|||
|
# 下一页
|
|||
|
if self.page < self.total_count_page:
|
|||
|
self.query_dict.setlist(self.page_param, [self.page + 1])
|
|||
|
prev = f'<li><a href="?{self.query_dict.urlencode()}">下一页</a></li>'
|
|||
|
page_list.append(prev)
|
|||
|
# 尾页
|
|||
|
# prev = f'<li><a href="?page={total_count_page}">尾页</a></li>'
|
|||
|
self.query_dict.setlist(self.page_param, [self.total_count_page])
|
|||
|
prev = f'<li><a href="?{self.query_dict.urlencode()}" aria-label="Previous"><span aria-hidden="true">»</span></a></li>'
|
|||
|
page_list.append(prev)
|
|||
|
|
|||
|
# 构建跳转html
|
|||
|
page_nav_search = """
|
|||
|
<li>
|
|||
|
<form method="get" style="float: left;margin-left: -1px">
|
|||
|
<input style="width: 100px;position: relative;float: left;display: inline-block;border-radius: 0" type="text" name="indexPage" class="form-control" placeholder="页码..">
|
|||
|
<button style="border-radius: 0;" class="btn btn-default" type="submit">跳转</button>
|
|||
|
</form>
|
|||
|
</li>
|
|||
|
"""
|
|||
|
page_list.append(page_nav_search)
|
|||
|
|
|||
|
page_nav = ''.join(page_list)
|
|||
|
|
|||
|
# 因为page_nav是一个html字符串,所以在传递到前端时要转换为安全的字符串
|
|||
|
page_nav = mark_safe(page_nav)
|
|||
|
|
|||
|
"""分页实现结束"""
|
|||
|
return page_nav
|