网页中经常会用到分页,django中自带的paginator为我们很好的实现了分页功能。虽然其中还有些功能待完善,例如paginator会为我们将所有的页码全部展现出来,如果页码过多的话,全部显示就不太合理了,此时我们可以通过重写paginator类去实现我们想要的结果。
想要使用分页功能首先需要导入:
from django.core.paginator import Paginator
使用:
paginator = Paginator(List_info,num) # List_info表示传入的总数据,num表示每页显示的数据
其中paginator对象含有的属性:
per_page:每页显示的数据条数
count:数据总数
num_pages:总页数
page_range:总页数索引范围
page:page对象
page对象含有的方法:
has_next:判断是否有下一页
has_previous:判断是否有上一页
objects_list:分页之后的数据列表
next_page_number:下一页页码
previous_page_number:上一页页码
number:当前页(属性)
paginator:paginator对象
下面我们写一个简单的分页展示:
后端代码:
class PaginatorView(View):
def get(self,request):
current_page = request.GET.get("page",1)
all_name_obj = PaginatorTest.objects.all()
paginator = Paginator(all_name_obj,10)
page = paginator.page(current_page)
return render(request,"paginator_list.html",locals())
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<ul>
{% for name_obj in page %}
<li>{{ name_obj.name }}</li>
{% endfor %}
</ul>
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li class="active">
<a href="/buyer/paginator/?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %}
{% for current_page in paginator.page_range %}
{% if page.number == current_page %}
<li class="active">
<a href="/buyer/paginator/?page={{ current_page }}">{{ current_page }}</a>
</li>
{% else %}
<li>
<a href="/buyer/paginator/?page={{ current_page }}">{{ current_page }}</a>
</li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li class="active">
<a href="/buyer/paginator/?page={{ page.next_page_number }}" aria-label="Previous">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</body>
</html>
此时页面展示如下:
可以看到,页面中将所有的页码全部展示出来了,显示效果很不好看,如果想要只展示当前页的前几页页码和后几页页码应该如何实现呢,其他的页面用“...”代替,同时第一页和最后一页永远显示应该如何实现呢?
直接上代码:
class MyPaginator(Paginator): # 继承Paginator
def __init__(self,object_list, per_page, show_count=3, orphans=0, allow_empty_first_page=True): # show_count代表要展示的当前页之前或之后的页码数,默认展示3页
super().__init__(object_list, per_page, orphans, allow_empty_first_page) #继承父类的属性和方法
self.show_count = show_count
self.has_previous_more = True #定义show_count之前是否还有更多页码
self.has_next_more = True #定义show_count之后是否还有更多页码
#覆写page方法
def page(self, number):
self.number = int(number)
#判断当前页之前是否还有show_count显示的页码数
if self.number <= self.show_count + 2:
self.has_previous_more = False
self.previous_range = range(1,self.number)
else:
self.previous_range = range(self.number - self.show_count, self.number)
#判断当前页之后是否还有show_count显示的页码数
if self.number >= self.num_pages - self.show_count - 1:
self.has_next_more = False
self.next_range = range(self.number + 1, self.num_pages + 1)
else:
self.next_range = range(self.number + 1, self.number + self.show_count + 1)
return super().page(number)
class PaginatorView(View):
def get(self,request):
current_page = request.GET.get("page",1)
all_name_obj = PaginatorTest.objects.all()
paginator = MyPaginator(all_name_obj,10) #可增加第三个参数确定当前页之前或之后展示的页码数
page = paginator.page(current_page)
return render(request,"paginator_list.html",locals())
前端代码:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<ul>
{% for name_obj in page %}
<li>{{ name_obj.name }}</li>
{% endfor %}
</ul>
<div>
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li class="active">
<a href="/buyer/paginator/?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">上一页</span>
</a>
</li>
{% endif %}
{% if paginator.has_previous_more %}
<li><a href="/buyer/paginator/?page=1">1</a></li>
<li><a href="javascript:void(0);">...</a></li>
{% endif %}
{% for previous_page in paginator.previous_range %}
<li><a href="/buyer/paginator/?page={{ previous_page }}">{{ previous_page }}</a></li>
{% endfor %}
<li class="active"><a href="/buyer/paginator/?page={{ page.number }}">{{ page.number }}</a></li>
{% for next_page in paginator.next_range %}
<li><a href="/buyer/paginator/?page={{ next_page }}">{{ next_page }}</a></li>
{% endfor %}
{% if paginator.has_next_more %}
<li><a href="javascript:void(0);">...</a></li>
<li><a href="/buyer/paginator/?page={{ paginator.num_pages }}">{{ paginator.num_pages }}</a></li>
{% endif %}
{% if page.has_next %}
<li class="active">
<a href="/buyer/paginator/?page={{ page.next_page_number }}" aria-label="Previous">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="javascript:void(0);" aria-label="Previous">
<span aria-hidden="true">下一页</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</body>
</html>
页面效果:
这样我们就完善了django自带的paginator分页功能,可以完美展示我们想要的各种分页效果。