封装分页类
封装 pagination.py 类, 需要的页面导入就行
"""
自定义的分页组件, 以后如果想要使用分页组件,需要如下:
在视图函数中(views.py):
def num_list(request):
# 1. 根据直实需求筛选需要的数据
queryset = models.PrettyNum.objects.all()
# 2. 实例化分页对象
page_object = Pagination(request, queryset)
# 3. 返回到html的数据
context = {
# 分完页的数据
'queryset': page_object.page_queryset,
# 数据计数
'count': queryset.count(),
# 生成页码
'page_string': page_object.html(),
}
return render(request, 'num_list.html', context=context)
在HTML页面中
{% for obj in queryset %}
{{ obj.xx }}
{% endfor %}
<ul class="pagination">
{{ page_string }}
</ul>
"""
from django.utils.safestring import mark_safe
import copy
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_param='page', plus=5):
"""
:param request: 请求的对象,需要传入
:param queryset: 符合条件的查询数据(根据这个数据进行分布处理),需要传入
:param page_size: 每页多少条数据,如不传入默认是10条
:param page_param: 在URL里传递的获取分页的参数,例如:/prettynum/list/?page=4
:param plus: 显示当前选中页的 前后各几页
"""
# 拿到浏览器 get方式传过来的page, 不需要传入
page = request.GET.get(page_param, '1')
# 判断页码,如果是数字,int转换
if page.isdecimal():
page = int(page)
else:
# 非数字 赋值为1
page = 1
# 当前页
self.page = page
# 每页显示的数据条数
self.page_size = page_size
# 显示分页数据起始值和结束值
# 规律:当前页码-1*10 到 当前页码*10
self.start = (page - 1) * page_size
self.end = page * page_size
# 分完页的数据
# queryset 是 对象传入的参数:根据条件筛选的数据,
# [self.start:self.end]-包含了数据起始值和结束值]
self.page_queryset = queryset[self.start:self.end]
# 计算总条数
self.count = queryset.count()
# 计算总页码 self.total_page_count # 除法,divmod 取商和余数
self.total_page_count, self.div = divmod(self.count, page_size)
if self.div > 0:
self.total_page_count += 1
# 显示当前页的 前5页 和 后5页
self.plus = plus
# 拼接 url传过来的GET参数
# 生拷贝了一份request.GET
query_dict = copy.deepcopy(request.GET)
# 修改源码,允许修改
from django.http.request import QueryDict
query_dict._mutable = True
# 包含了原来的url参数(比如:搜索条件)
self.query_dict = query_dict
# 增加的带页码的参数
self.page_param = page_param
def html(self):
# 计算出,
# 如果总页码小于等于 11 页,就在一页显示完所有页码,合计11页码
if self.total_page_count <= self.plus * 2 + 1:
# 起始页
start_page = 1
# 结尾页
end_page = self.total_page_count
# 超过11页 显示前5,当前和后5
else:
# 当前页小于5,防止起始页出现 -负数
if self.page <= self.plus:
start_page = 1
end_page = self.plus * 2 + 1
else:
# 当前页 +5 > 总页码的情况:
if (self.page + self.plus) > self.total_page_count:
start_page = self.page - self.plus
end_page = self.total_page_count
else:
start_page = self.page - self.plus
end_page = self.page + self.plus
# 后台需要生成的html标签页码
page_str_list = [] # [‘li标签1’,'li标签2',......'li标签19']
# 首页
self.query_dict.setlist(self.page_param, [1])
page_str_list.append('<li ><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
# 上一页 page 是当前页 -1前一页 , 格式化字符串
if self.page > 1:
self.query_dict.setlist(self.page_param, [self.page - 1])
prev = '<li ><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [1])
prev = '<li ><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
# 页面
# range 前取后不取,所以+1
# for i in range(1, total_page_count+1):
for i in range(start_page, end_page + 1):
self.query_dict.setlist(self.page_param, [i])
# ?page=值
# 如果循环到当前页,增加一个 class="active" 样式,高亮显示激活状态
if i == self.page:
ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
else:
ele = '<li ><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
page_str_list.append(ele)
# 下一页 当前页小于总页数
if self.page < self.total_page_count:
self.query_dict.setlist(self.page_param, [self.page + 1])
next = '<li ><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [self.total_page_count])
next = '<li ><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(next)
# 尾页
self.query_dict.setlist(self.page_param, [self.total_page_count])
page_str_list.append('<li ><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
# 跳转
skip_string = """
<li>
<form method="get" style="float: left; margin-left: -1px">
<input name="page"
style="position: relative; float: left; display: inline-block;width: 80px; border-radius: 0"
type="text" class="form-control" placeholder="页码">
<button style="border-radius: 0" class="btn btn-default" type="submit">跳转</button>
</form>
</li>
"""
page_str_list.append(skip_string)
# diango 框架下,直接写html格式,需要标记 mark_safe
# from django.utils.safestring import mark_safe
# 标记安全的字符串转html标签 make_safe 需要导入
# join() 将元素按照分隔符「拼接」成新的字符串, ''空分隔符
# 传到前端
page_string = mark_safe(''.join(page_str_list))
# 将 page_string 返回到前端
return page_string