django_project_demo/app/utils/pagination.py
2024-08-24 03:25:23 +00:00

143 lines
5.9 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""
分页组件,武沛奇视频课件讲解
"""
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