自定义的分页组件,以后想要使用分页组件需要做如下几件事:
# 在试图函数中
def phone_list(request):
# 1. 根据自己的情况筛选数据
queryset = models.PrettyNum.objects.all()
# 2.实例化分页对象
page_object = Pagination(request, queryset)
context = {
"phone": page_object.page_queryset, # 分完页的数据
"page_string": page_object.html() # 页码
}
return render(request, "phone_list.html", context)
在html页面中:
<ul class="pagination">
{{ page_string }}
</ul>
1. 分页封装
class Pagination(object):
def __init__(self, request, queryset, page_size=10, page_pram="page", plus=5):
"""
reuqest: 请求的对象
queryset: 符合条件的数据(根据这个数据进行分页处理)
page_size:每页显示多少条数据
page_pram: 在url中传递的获取分页的参数,例如: /phone/list?page=12
plus: 显示当前页的,前后几页(页码)
"""
from django.http.request import QueryDict
import copy
querty_dict = copy.deepcopy(request.GET) # 深拷贝get请求内容
# 在正常的请求/响应周期中访问时,request.POST和request.GET上的QueryDict将是不可变的.
# 要获得可变版本,您需要使用QueryDict.copy()或者._mutable = True
querty_dict._mutable = True
self.querty_dict = querty_dict # 将获取到的get内容重新赋值
self.page_pram = page_pram # 在url中传递的获取分页的参数,例如: /phone/list?page=12
# 对当前页进行判断
page = request.GET.get(page_pram, "1") # 获取当前页
if page.isdecimal(): # 检查字符串是否只包含十进制字符/如果字符串中的所有字符都是十进制字符。返回true,有一个不是则返回False
page = int(page)
else:
page = 1
self.page = page # 获取当前页
self.page_size = page_size # 每页显示条数
# 每页显示10条的内容
self.start = (page - 1) * page_size # 起始值
self.end = page * page_size # 结束值
# 到前端访问展示的页面:self.page_queryset
self.page_queryset = queryset[self.start:self.end] # 将从数据库获取到的内容进行切片-分页
# 获取数据库的总条数
phone_count = queryset.count()
# 总页码: 总条数 / 每页显示条数 = 总页数 零 几条
phone_page_count, div = divmod(phone_count, page_size) # divmod(): 两数相除,得到元祖,两个值,一个商,一个余数
if div: # 如果有余数,则总页数+1
phone_page_count += 1
self.phone_page_count = phone_page_count
self.plus = plus # 前后显示几页
def html(self):
# 计算出,显示当前页的前后5页
if self.phone_page_count <= 2 * self.plus + 1: # 判断页码是否小于 前后页相加
# 数据库中的数据比较少,没有达到 前后页总和 ,那就起始页=1 ,结束页=总页
start_page = 1
end_page = self.phone_page_count
else:
# 数据库中的数据比较多 > 前后页总和页
# 当前页小于 前页5 时(小极值)
if self.page <= self.plus: # 判断起始页
start_page = 1
end_page = 2 * self.plus + 1
else: # 判断尾页
# 当前页大于后页5
# 当前页 + 后页5 > 总页码
if self.page + self.plus > self.phone_page_count:
start_page = self.phone_page_count - 2 * self.plus
end_page = self.phone_page_count
else: # 正常显示
start_page = self.page - self.plus
end_page = self.page + self.plus
# 页码
from django.utils.safestring import mark_safe # 导入,表示标签是安全的,才会在前端展示
page_str_list = []
self.querty_dict.setlist(self.page_pram, [1]) # 允许设置自己的路径参数 page,1
# print(request.GET.urlencode()) # 带着原来的参数加上自己的参数,拼接url
# 首页
page_str_list.append('<li><a href="?{}">首页</a></li>'.format(self.querty_dict.urlencode())) # page=1
# print("self.querty_dict.urlencode()=", self.querty_dict.urlencode())
# 判断page
# 上一页
if self.page > 1:
self.querty_dict.setlist(self.page_pram, [self.page - 1]) # 设置自己的路径参数
prev = '<li><a href="?{}">上一页</a></li>'.format(self.querty_dict.urlencode())
else:
self.querty_dict.setlist(self.page_pram, [1]) # 设置自己的路径参数 page=1
prev = '<li><a href="?page={}">上一页</a></li>'.format(self.querty_dict.urlencode())
page_str_list.append(prev)
# 页面
for i in range(start_page, end_page + 1): # 循环所有页
self.querty_dict.setlist(self.page_pram, [i]) # 设置自己的路径参数
if i == self.page: # 加个样式:class="active"
ele = '<li class="active"><a href="?{}">{}</a></li>'.format(self.querty_dict.urlencode(), i)
else:
ele = '<li><a href="?{}">{}</a></li>'.format(self.querty_dict.urlencode(), i)
page_str_list.append(ele)
# print("page_str_list=",page_str_list)
# 下一页
if self.page < self.phone_page_count:
self.querty_dict.setlist(self.page_pram, [self.page + 1]) # 设置自己的路径参数
prev = '<li><a href="?{}">下一页</a></li>'.format(self.querty_dict.urlencode())
else:
self.querty_dict.setlist(self.page_pram, [self.phone_page_count]) # 设置自己的路径参数
prev = '<li><a href="?{}">下一页</a></li>'.format(self.querty_dict.urlencode())
page_str_list.append(prev)
# 尾页
self.querty_dict.setlist(self.page_pram, [self.phone_page_count]) # 设置自己的路径参数
page_str_list.append('<li><a href="?{}">尾页</a></li>'.format(self.querty_dict.urlencode()))
# 前端跳转功能
search_string = """
<li>
<form style="float:left; margin-left:-1px;" method="get">
<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(search_string)
# print("-----",page_str_list)
page_string = mark_safe("".join(page_str_list)) # 表示安全的
return page_string
2. 视图函数调用
def user_list(request):
"""用户表"""
queryset = models.User.objects.all()
from app01.utils.pagemtion import Pagination # 导入分页类
page_object = Pagination(request, queryset, page_size=2)
context = {
"querty": page_object.page_queryset,
"page_string": page_object.html()
}
return render(request, "user_list.html", context)
3. html调用
<ul class="pagination">
{{ page_string }}
</ul>