一、Django分页功能
1.Paginator对象
| 方法 | 描述 |
|---|---|
| per_page | 每页显示条目数量 |
| count | 数据总个数 |
| num_pages | 总页数 |
| page_range | 总页数的索引范围,如: (1,10),(1,200) |
| page | page对象 |
2.page对象
| 方法 | 描述 |
|---|---|
| has_next | 是否有下一页 |
| next_page_number | 下一页页码 |
| has_previous | 是否有上一页 |
| previous_page_number | 上一页页码 |
| object_list | 分页之后的数据列表 |
| number | 当前页 |
| paginator | paginator对象 |
3.内置分页功能
views.py文件
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
User_list = []
for i in range(1,101):
item = {"user"+str(i):i}
User_list.append(item)
def index1(request):
current_page = request.GET.get("p")
paginator = Paginator(User_list, 10)
try:
# 这里将page对象定于为 ports
ports = paginator.page(current_page)
except PageNotAnInteger:
ports = paginator.page(1)
except EmptyPage:
ports = paginator.page(paginator.num_pages)
return render(request,"index1.html", {"ports":ports})
views.py
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
{% for user in ports.object_list %}
<ul>{{ user }}</ul>
{% endfor %}
<div>
{% if ports.has_previous %}
<a href="/index1.html/?p={{ ports.previous_page_number }}">上一页</a>
{% else %}
<a href="#">首页</a>
{% endif %}
{% if ports.has_next %}
<a href="/index1.html/?p={{ ports.next_page_number }}">下一页</a>
{% else %}
<a href="#">尾页</a>
{% endif %}
</div>
</body>
</html>

Django内置的分页功能就只能做到这些事情,但这远远不能满足我们的需求,那么我们就需要对Django分页功能进行补充了。
二、Django分页功能的补充
- 类Paginator是由Django内置的一个分页功能,但它能够完成的功能有限,那么我们就需要对其进行补充了。
- 我们自定义CustomPaginator类,该类继承Paginator
扩展内置分页:views.py
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
class CustomPaginator(Paginator):
def __init__(self, current_page, max_pager_num, *args, **kwargs):
"""
:param current_page: 当前页
:param max_pager_num:最多显示的页码个数
:param args:
:param kwargs:
:return:
"""
self.current_page = int(current_page)
self.max_pager_num = max_pager_num
super(CustomPaginator, self).__init__(*args, **kwargs)
def page_num_range(self):
# 当前页面
# self.current_page
# 总页数
# self.num_pages
# 最多显示的页码个数
# self.max_pager_num
print(1)
if self.num_pages < self.max_pager_num:
return range(1, self.num_pages + 1)
print(2)
part = int(self.max_pager_num / 2)
if self.current_page - part < 1:
return range(1, self.max_pager_num + 1)
print(3)
if self.current_page + part > self.num_pages:
return range(self.num_pages + 1 - self.max_pager_num, self.num_pages + 1)
print(4)
return range(self.current_page - part, self.current_page + part + 1)
L = []
for i in range(999):
L.append(i)
def index(request):
current_page = request.GET.get('p')
paginator = CustomPaginator(current_page, 11, L, 10)
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
try:
posts = paginator.page(current_page)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
except PageNotAnInteger:
posts = paginator.page(1)
except EmptyPage:
posts = paginator.page(paginator.num_pages)
return render(request, 'index.html', {'posts': posts})
扩展内置分页:Html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
<div>
<a href="/index1.html/?p=1">首页</a>
{% if ports.has_previous %}
<a href="/index1.html/?p={{ ports.previous_page_number }}">上一页</a>
{% endif %}
{% for foo in ports.paginator.page_num_range %}
{% if foo == ports.number %}
<a href="/index1.html/?p={{ foo }}" style="font-size: 30px;color: red">{{ foo }}</a>
{% else %}
<a href="/index1.html/?p={{ foo }}">{{ foo }}</a>
{% endif %}
{% endfor %}
{% if ports.has_next %}
<a href="/index1.html/?p={{ ports.next_page_number }}">下一页</a>
{% endif %}
<a href="/index1.html/?p={{ ports.paginator.num_pages }}">尾页</a>
<span>{{ ports.number }}/{{ ports.paginator.num_pages }}</span>
</div>
</body>
</html>
扩展内置分页:Html
通过该分页功能大致实现的效果

三、自定制插件式分页功能
除了用系统提供的,我们可以自定义一个插件功能,这样的话,我们只需要将这个py文件保存在我们电脑的硬盘中,在我们需要时,调用就可以实现分页了,同时在定制时,还能为分页设置好样式。
在这里我们使用BootStrap来对我们的样式进行美化。
views.py文件
def index(request):
from app.pager import Pagination
current_page = request.GET.get("p")
print(current_page)
page_obj = Pagination(total_count=len(User_list),
current_page=current_page)
print(page_obj.num_pages)
data_list = User_list[page_obj.start():page_obj.end()]
return render(request,"index.html",{"data_list":data_list,"page_obj":page_obj})
插件page.py文件
""""
配合插件 Bootstrap
"""
class Pagination(object):
def __init__(self,total_count,current_page,per_page_num=20,max_page_num=7):
"""
:param total_count: 所有数据的个数
:param current_page: 当前页码
:param per_page_num: 每页显示记录个数
:param max_page_num: 分页现在最多页码个数
"""
self.total_count=total_count
try:
self.current_page=int(current_page)
if self.current_page < 1:
self.current_page = 1
except Exception as e:
self.current_page = 1
self.per_page_num=per_page_num
self.max_page_num=max_page_num
# 数据的索引首地址
def start(self):
return (self.current_page-1)*self.per_page_num
# 数据的索引为地址
def end(self):
return (self.current_page)*self.per_page_num
@property
def num_pages(self):
"""
:return: 总页数
"""
a,b = divmod(self.total_count,self.per_page_num)
if self.per_page_num == 0:
return a
return a+1
def page_num_range(self):
"""
自定义分页功能
:return: 返回值是一个数组,该数组表示的是分页显示的页码
"""
part = int(self.max_page_num/2) # 分页个数的中间值
# 当页码总数小于显示分页数目时,所有页码显示
if self.num_pages <= self.max_page_num:
return range(1, self.num_pages+1)
elif self.num_pages > self.max_page_num:
# 当前页码小于分页的总数的中间值时,显示前几位分页页码
if self.current_page<=part:
return range(1,self.max_page_num+1)
# 当前页码+中间值时大于总页码,显示后几位分页页码
elif self.current_page+part>=self.num_pages:
return range(self.num_pages - self.max_page_num + 1, self.num_pages + 1)
# 显示需要显示的页码个数,并将当前页码居中
return range(self.current_page-part,self.current_page+part+1)
def page_str(self):
"""
:return: 返回值是一个html格式的字符串,返回到前端直接调用就可以显示页码。运用的是插件Bootstrap
"""
page_list = []
# 首页按钮
first_page = "<ul class='pagination'> <li ><a href='/index.html/?p=1'>首页</a></li>"
page_list.append(first_page)
# 如果存在上一页才有上一页按钮
if self.current_page>1:
prep_page = "<li><a href='/index.html/?p=%s'>上一页</a></li>"%(self.current_page-1)
page_list.append(prep_page)
# 中间序列的页码按钮
for i in self.page_num_range():
if i == self.current_page:
temp = "<li class='active'><a href='/index.html/?p=%s' >%s</a></li>"%(i,i)
else:
temp = "<li><a href='/index.html/?p=%s' >%s</a></li>"%(i,i)
page_list.append(temp)
# 如果存在下一页才有下一页按钮
if self.current_page< self.num_pages:
next_page = "<li><a href='/index.html/?p=%s'>下一页</a></li>"%(self.current_page+1)
page_list.append(next_page)
# 尾页按钮
last_page = "<li><a href='/index.html/?p=%s'>尾页</a></li> </ul>"%(self.num_pages)
page_list.append(last_page)
return " ".join(page_list)
index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="/static/plugin/bootstrap/css/bootstrap.css">
<style>
* {
padding: 0;
margin: 0;
}
</style>
</head>
<body>
{% for row in data_list %}
<ul>{{ row }}</ul>
{% endfor %}
<hr>
{% for current_page in page_obj.page_num_range %}
<a href="/index.html/?p={{ current_page }}">{{ current_page }}</a>
{% endfor %}
<hr>
{{ page_obj.page_str | safe }}
</body>
</html>
通过该自定义插件,我们可以对比出,渲染后的区别

本文介绍了Django框架中的分页功能,包括Paginator对象、page对象及内置分页的使用。详细讲解了如何扩展Django内置分页,通过自定义CustomPaginator类并实现分页功能的补充。此外,还展示了如何使用BootStrap进行样式美化,提供了一个自定义插件式的分页解决方案,使得分页效果更加灵活且易于调用。
2060

被折叠的 条评论
为什么被折叠?



