【Django】分页组件封装与调用
"""
自定义的分页组件,以后如果想要使用这个分页组件,你需要做如下几件事:
在视图函数中:
def pretty_list(request):
# 1.根据自己的情况去筛选自己的数据
queryset = models.PrettyNum.objects.all()
# 2.实例化分页对象
page_object = Pagination(request, queryset)
context = {
"queryset": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 生成页码
}
return render(request, 'pretty_list.html', context)
在HTML页面中
{% for obj in queryset %}
{{obj.xx}}
{% endfor %}
<ul class="pagination">
{{ page_string }}
</ul>
"""
import math
from django.shortcuts import render
from django.utils.safestring import mark_safe
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_param="page", plus=5):
"""
:param request: 请求的对象
:param queryset: 符合条件的数据(根据这个数据给他进行分页处理)
:param page_size: 每页显示多少条数据
:param page_param: 在URL中传递的获取分页的参数,例如:/etty/list/?page=12
:param plus: 显示当前页的 前或后几页(页码)
"""
import copy
query_dict = copy.deepcopy(request.GET)#复制query
query_dict._mutable = True #设置query可以修改
self.query_dict = query_dict
self.page_param = page_param # 获取分页的参数,在分页组件中是 "page"
page = request.GET.get(page_param, "1")
#默认值是字符串的1是为了能够支持更多可能的数据类型,
#可能以后我们封装数据接口的时候不一定是数据类型,
#所以要把转化为int的工作放在下面的代码中
if page.isdecimal():
page = int(page)#转化为int类型
else:
page = 1
self.page = page
self.page_size = page_size # 每一页记录个数
self.start = (page - 1) * page_size # 记录开始的区间
self.end = page * page_size # 记录结束的区间
self.page_queryset = queryset[self.start:self.end] #获取当前页码的数据
#total_count = models.PrettyNum.objects.all().count() # 统计所有数据记录数
total_count = queryset.count()# 统计所有数据记录数
# 页码
self.plus = 5 # 当前页面 前后几页的数值
self.total_page= math.ceil(total_count / 10) # 总共页面数
def html(self):
page_str_list = []
if self.total_page < 2 * self.plus + 1: # 页面过少,起始和结束页码改为1和总页面数
start_page = 1
end_page = self.total_page
elif self.page < 1 + self.plus: # 避免出现负数页码
start_page = 1
end_page = self.page + self.plus
elif self.page + self.plus > self.total_page: # 避免超过总页数
start_page = self.page - self.plus
end_page = self.total_page # +1是因为range闭区间
else:
start_page = self.page - self.plus # 当前页面
end_page = self.page + self.plus
# 首页
self.query_dict.setlist(self.page_param, [1])
page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
# 上一页
if self.page <= 1:
self.query_dict.setlist(self.page_param, [1])
prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
else:
self.query_dict.setlist(self.page_param, [self.page - 1])
prev = '<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode())
page_str_list.append(prev)
# for i in range(1, 21):
for i in range(start_page, end_page + 1): # (306/10)=30.6->向上取整31 ->因为range右边闭区间还要+1
if i == self.page: # 如果是当前所在页面,添加激活样式
self.query_dict.setlist(self.page_param, [i])
ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(),i) # 生成多行页码li
else:
self.query_dict.setlist(self.page_param, [i])
ele = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(),i) # 生成多行页码li
page_str_list.append(ele) # 添加到一个列表中
# 下一页
if self.page < self.total_page: # 判断是否超过总页数
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])
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])
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
# 分页搜索框
search_string = '''
<form method="get">
<div class="input-group" style="width:200px">
<input type="text" name="page" class="form-control" value="" placeholder="页码">
<span class="input-group-btn">
<button class="btn btn-default" type="submit">跳转</button></span>
</div>
</form>
'''
page_str_list.append(search_string)
# page_string = "".join(page_str_list) # 用""分隔符将列表页码的代码连接形成的字符串,需要加个安全信任才能变成html
page_string = mark_safe("".join(page_str_list)) # 用""分隔符将列表页码的代码连接形成的字符串,需要加个安全信任才能变成html
return page_string
本文来自博客园,作者:木子欢儿,转载请注明原文链接:https://www.cnblogs.com/HGNET/p/17310512.html