目录
1. 前言
2. 代码
3. 使用
3.1 view.py
3.2 list.html
1. 前言
在日常开发中,我们也许会遇到一页内容太多不够展示的问题,过于冗余。
此时,我们就需要进行分页,分页的方式有两种:1. ajax异步分页 2. 普通选择分页
这里介绍的组件就是普通分页组件,看效果:
除此之外,如果页数过多,只会显示当前前面五页和后面五页:
废话不多说,直接上代码!
2. 代码
分页器:
import copy
from django.utils.safestring import mark_safe
class Pagination(object):
""" 分页 """
def __init__(self, request, query_set, per_page_count=10):
"""
分页初始化
:param request: 请求参数
:param query_set: 数据
:param per_page_count: 页数
"""
# 请求传递过来的GET参数,深拷贝一份,避免修改原始请求数据
self.query_dict = copy.deepcopy(request.GET)
# GET对象默认是无法修改的,这个可以让此对象能够被修改,因为后续我们要构造page(页码)参数
self.query_dict._mutable = True
self.query_set = query_set
total_count = query_set.count()
self.total_count = total_count
# 计算出总共有多少页面
self.total_page, div = divmod(total_count, per_page_count)
if div:
self.total_page += 1
# 字符串格式
page = request.GET.get('page', "1")
# 判断内容是否是数字
if not page.isdecimal():
page = 1
else:
page = int(page)
if page <= 0:
page = 1
if page > self.total_page:
page = self.total_page
self.page = page
self.per_page_count = per_page_count
self.start = (page - 1) * per_page_count
self.end = page * per_page_count
def html(self):
# 最后拼接的内容
pager_list = []
if not self.total_page:
return ""
# 构造显示的页数
# 总页码小于11
if self.total_page <= 11:
start_page = 1
end_page = self.total_page
else:
# 总页码比较多
# 判断当前页 <=6: 1~11
if self.page <= 6:
start_page = 1
end_page = 11
else:
if (self.page + 5) > self.total_page:
start_page = self.total_page - 10
end_page = self.total_page
else:
start_page = self.page - 5
end_page = self.page + 5
# 样式相关
pager_list.append('<ul class="pagination">')
self.query_dict.setlist('page', [1])
pager_list.append('<li><a href="?{}">首页</a></li>'.format(self.query_dict.urlencode()))
if self.page > 1:
self.query_dict.setlist('page', [self.page - 1])
pager_list.append('<li><a href="?{}">上一页</a></li>'.format(self.query_dict.urlencode()))
for i in range(start_page, end_page + 1):
self.query_dict.setlist('page', [i])
if i == self.page:
item = '<li class="active"><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
else:
item = '<li><a href="?{}">{}</a></li>'.format(self.query_dict.urlencode(), i)
pager_list.append(item)
if self.page < self.total_page:
self.query_dict.setlist('page', [self.page + 1])
pager_list.append('<li><a href="?{}">下一页</a></li>'.format(self.query_dict.urlencode()))
self.query_dict.setlist('page', [self.total_page])
pager_list.append('<li><a href="?{}">尾页</a></li>'.format(self.query_dict.urlencode()))
pager_list.append('<li class="disabled"><a>数据{}条{}页</a></li>'.format(self.total_count, self.total_page))
pager_string = mark_safe("".join(pager_list))
pager_list.append('</ul>')
return pager_string
def queryset(self):
"""
返回具体的数据
:return:
"""
if self.total_count:
return self.query_set[self.start:self.end]
return self.query_set
其中,__init__是初始化方法,html函数是显示在页面上面的样式,之所以采用这种方式来写样式,是因为能够更好的动态显示页码,queryset函数就是元素展示。
3. 使用
3.1 view.py
def list(request):
queryset =models.Level.objects.all()
pager = Pagination(request, query_set=queryset, per_page_count=1)
context = {
'queryset': pager.queryset(),
'html': pager.html(),
}
return render(request, 'list.html', {'pager': context})
3.2 list.html
{% load static %}
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<link rel="stylesheet" href="{% static 'plugins/bootstrap/css/bootstrap.min.css' %}">
<link rel="stylesheet" href="{% static 'plugins/font-awesome/css/font-awesome.min.css' %}">
</head>
<body>
{% for foo in pager.queryset %}
{{ foo }}
{% endfor %}
{{ pager.html }}
</body>
</html>
记得加上相关样式哟,我这里用的是BootStrap