一、在views中实现分页功能
views.py
def depart_list(request):
depart_all = models.Depart.objects.all()
# 分页 每页最多显示10条记录
obj_total = depart_all.count()
try:
# 如果获取不到page参数,将page_id默认设置成1
page_id = int(request.GET.get('page', 1))
except Exception as e:
page_id = 1
# 第1页切片,[0:10],取id为0-9的10条记录
# 第2页切片,[10:20],取id为10-19的10条记录
# 第n页切片,[(n-1)*10:n*10]
obj_start = (page_id - 1) * 10
obj_end = page_id * 10
# 总页码数为page_num
page_num, more = divmod(obj_total, 10)
if more:
# 如果有余数,则页码数加1
page_num += 1
# 第1页序号从1-10,第2页序号从11-20,而前端forloop.counter是从0开始,所以每页序号起始值要加上(n-1)*10
obj_id_start = (page_id - 1) * 10
# 每页的页码范围
page_start = (page_id - 1) // 10 * 10 + 1
page_end = page_start + 10
# 如果结束页码大于总页码,就以总页码数为结尾
if page_end > page_num:
page_end = page_num + 1
return render(request, 'depart/depart_list.html',
{'depart_all': depart_all[obj_start:obj_end],
# 'page_total': range(1, page_num + 1), # 显示所有的分页页码
'page_total': range(page_start, page_end), # 显示页码范围
'obj_id_start': obj_id_start,
})
user_list.html
{#分页#}
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{#向前翻页链接#}
{{ page_previous }}
{% for num in page_total %}
{#num等于当前页码时,显示active#}
<li {% if page_id == num %}class="active"{% endif %}><a href="?page={{ num }}">{{ num }}</a></li>
{% endfor %}
{#向后翻页链接#}
{{ page_next }}
</ul>
</nav>
</div>
二、分页功能封装成类
由于在views.py中编写了大量分页的功能,与核心逻辑无关,所以最好能将分页功能单独封装成类,再在views中调用
新建utils目录中的paginate.py用于封装分页类
from django.utils.safestring import mark_safe
class Paginate:
def __init__(self, obj_all, page_id, obj_max=10, page_max=10):
self.obj_total = obj_all.count()
# 分页 每页显示的条目数,默认最多显示10条记录
self.obj_max = obj_max
# 每页最多显示的页码个数
self.page_max = page_max
try:
# 如果获取不到page参数,将page_id默认设置成1
self.page_id = page_id
except Exception as e:
self.page_id = 1
# 总页码数为page_num
self.page_total, more = divmod(self.obj_total, obj_max)
if more:
# 如果有余数,则页码数加1
self.page_total += 1
# 第1页切片,[0:10],取id为0-9的10条记录
# 第2页切片,[10:20],取id为10-19的10条记录
# 第n页切片,[(n-1)*10:n*10]
#通过@property将方法封装成属性,在调用实例化对象.方法时就不需要加括号执行
@property
def obj_start(self):
obj_start = (self.page_id - 1) * self.obj_max
return obj_start
@property
def obj_end(self):
obj_end = self.page_id * self.obj_max
return obj_end
@property
def obj_id_start(self):
# 第1页序号从1-10,第2页序号从11-20,而前端forloop.counter是从0开始,所以每页序号起始值要加上(n-1)*10
obj_id_start = (self.page_id - 1) * self.page_max
return obj_id_start
@property
def page_start(self):
# 每页的页码范围
page_start = (self.page_id - 1) // self.obj_max * self.page_max + 1
return page_start
@property
def page_end(self):
page_end = self.page_start + self.page_max
# 如果结束页码大于总页码,就以总页码数为结尾
if page_end > self.page_total:
page_end = self.page_total + 1
return page_end
@property
def page_previous(self):
# 向前翻页,如果页面起始值为1,则向前翻页链接禁用
if self.page_start == 1:
page_previous = '<li class="disabled"><a aria-label="Previous"><span aria-hidden="true">«</span></a></li>'
else:
page_previous = '<li><a href="?page=%s" aria-label="Previous"><span aria-hidden="true">«</span></a></li>' \
% (self.page_start - self.obj_max)
return mark_safe(page_previous)
@property
def page_next(self):
# 向后翻页,最后一页向后翻页链接禁用
if self.page_end == self.page_total + 1:
page_next = '<li class="disabled"><a aria-label="Next"><span aria-hidden="true">»</span></a></li>'
else:
page_next = '<li><a href="?page=%s" aria-label="Next"><span aria-hidden="true">»</span></a></li>' \
% (self.page_start + self.obj_max)
return mark_safe(page_next)
views.py文件中只需要实例化分页类并传参即可
def user_list(request):
user_all = models.User.objects.all()
#获取当前页面Url中的?page=id值,默认为1
page_id = int(request.GET.get('page', 1))
#实例化分页类
paginate = Paginate(user_all, page_id)
#返回参数,使用对象.参数的方法调用,由于类中使用了@property装饰器将方法封装成属性,所以不需要加括号即可执行
return render(request, 'user/user_list.html',
{'user_all': user_all[paginate.obj_start:paginate.obj_end],
'page_total': range(paginate.page_start, paginate.page_end), # 显示页码范围
'obj_id_start': paginate.obj_id_start,
'page_id': paginate.page_id,
'page_previous': paginate.page_previous,
'page_next': paginate.page_next,
})
user_list.html前端渲染
{#分页#}
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{#向前翻页链接#}
{{ page_previous }}
{% for num in page_total %}
{#num等于当前页码时,显示active#}
<li {% if page_id == num %}class="active"{% endif %}><a href="?page={{ num }}">{{ num }}</a></li>
{% endfor %}
{#向后翻页链接#}
{{ page_next }}
</ul>
</nav>
</div>