from django.utils.safestring import mark_safe
import copy
"""
自定义分页组件,使用方式:
def prettynum_list(request):
# 1.筛选数据
num_list = PrettyNum.objects.all()
# 2.实例化该类,并传入两个必要的参数
pagination_1 = Pagination(request=request, queryset=num_list)
# 3.返回对应的分页足组件
ele_string = pagination_1.html()
# 4.返回对应页元素的起始、结束索引
x, y = pagination_1.start_end()
show_list = num_list[x:y]
context = {'num_list': show_list, # 页面的数据
'element': ele_string, # 分页组件
}
return render(request, 'prettynum_list.html', context)
在HTML页面中:
{% for obj in num_list %}
<tr>
{{ obj.xx }}
</tr>
{% endfor %}
---------------------------------
<ul class="pagination">
{{ element }}
</ul>
"""
"""小bug:未解决跳转时,携带搜索框参数的问题(应该可以使用ajax解决)"""
class Pagination:
def __init__(self, request, queryset, page_size=10, pageparam='page', page_plus=5):
"""
:param request:请求的request
:param queryset:查询到的数据列表
:param page_size:每页显示的数据数量
:param pageparam:request携带的关于当前页码的参数名称,如:page,/prettynum/list/?page=91
:param page_plus:显示页码的范围,若为5,则显示当前页码前后各5个页码
"""
self.queryset = queryset
self.total = len(queryset)
self.plus = page_plus
self.page_size = page_size
self.pageparam = pageparam
query_dict = copy.deepcopy(request.GET) # 获取GET参数,并添加参数,因request.GET不可变,则深copy
# query_dict._mutable # 该属性控制是否可变,默认_mutable=True
self.query_dict = query_dict
if self.total == 0:
# 如果查询数据为0条,总页数置为1
self.total_pages = 1
else:
total_pages, div = divmod(self.total, page_size)
self.total_pages = total_pages + 1 if div else total_pages
# 获取当前页的页码,对非法情况进行处理
page = request.GET.get(pageparam, "1")
if page.isdecimal():
page = int(page)
else:
page = 1
if page < 1:
page = 1
elif page > self.total_pages:
page = self.total_pages
self.page = page
# left、right控制页码范围
left = self.page - self.plus
left = 1 if left < 1 else left
right = self.page + self.plus
right = self.total_pages if self.total_pages < right else right
self.right, self.left = right, left
# start、end控制显示的数据索引
if self.total != 0:
start = self.page * self.page_size - 9
end = self.page * self.page_size
end = self.total if end > self.total else end
self.start, self.end = start - 1, end
else:
self.start, self.end = 0, 0
def html(self):
"""
:return: 返回生成的分页组件
"""
elements = []
ele = '<li><a href="?{}">{}</a></li>'
self.query_dict.setlist(self.pageparam, [1])
elements.append(ele.format(self.query_dict.urlencode(), '首页'))
precious_page = 1 if self.page == 1 else self.page - 1
next_page = self.total_pages if self.page == self.total_pages else self.page + 1
self.query_dict.setlist(self.pageparam, [precious_page])
elements.append(ele.format(self.query_dict.urlencode(), '上一页'))
for i in range(self.left, self.right + 1):
self.query_dict.setlist(self.pageparam, [i])
if i == self.page:
# 当前页的页码高亮显示
element = '<li class="active"><a href="?{}">{}</a></li>'
else:
element = '<li><a href="?{}">{}</a></li>'
element = element.format(self.query_dict.urlencode(), i)
elements.append(element)
self.query_dict.setlist(self.pageparam, [next_page])
elements.append(ele.format(self.query_dict.urlencode(), '下一页'))
self.query_dict.setlist(self.pageparam, [self.total_pages])
elements.append(ele.format(self.query_dict.urlencode(), '尾页'))
result_str = mark_safe(''.join(elements)) # 字符串拼接后不可直接在页面展示,需要通过安全字符串
return result_str
def start_end(self):
"""
:return: 返回当前页数据的起始、结束索引,从0开始
"""
return self.start, self.end
Django自定义分页组件
于 2024-01-05 05:08:47 首次发布