Django 分页器
要使用Django实现分页功能,必须从Django中导入Paginator模块(painator - 分页器)
views.py
from django.shortcuts import render
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
from BookSite.models import *
def index(request):
"""
批量导入数据
book_list = []
for i in range(100):
book_list.append(Book(title="book"+str(i), price=30+i**2))
Book.objects.bulk_create(book_list)
"""
"""
分页器的使用
book_list = Book.objects.all()
paginator = Paginator(book_list, 10)
print("count:", paginator.count) # 总数居
print("num_pages", paginator.num_pages) # 总页数
print("page_range", paginator.page_range) # 页面的列表
page_one = paginator.page(1) # 第一页的page对象
for i in range(page_one): # 遍历第1页的所有数据对象
print(i)
print(page_one.object_list) # 第1页所有数据
page_two = paginator.page(2)
print(page_two.has_next()) # 是否有下一页
print(page_two.next_page_number()) # 下一页的页码
print(page_two.has_previous()) # 是否有上一页
print(page_two.previous_page_number()) # 上一页的页码
# 抛出错误
page = paginator.page(12) # Error:EmptyPage
page = paginator.page("z") # Error:PageNotAnInteger
"""
book_list = Book.objects.all()
paginator = Paginator(book_list, 10)
page = request.GET.get("page", 1)
current_page = int(page)
try:
print(page)
book_list = paginator.page(page)
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages)
return render(request, "index.html", {
"book_list": book_list,
"paginator": paginator,
"current_page": current_page
})
def retrieve(request):
"""
批量导入
book_list = []
for i in range(100):
book_list.append(models.Book(title="book"+str(i), price=20+i*i))
models.Book.objects.bulk_create(book_list)
"""
book_list = Book.objects.all() # book_list打印的是一个对象 查询所有的书
paginator = Paginator(book_list, 5) # 这里的book_list必须是一个集合对象,把所有的书分页,每页5个
print(paginator.page_range) # range(1, 4)
amount = request.GET.get("page", 2) # 得到页数范围 默认有1页
print(amount, type(amount))
book_list = paginator.page(amount) # 显示第1页的内容
return render(request, "retrieve.html", {
"book_list": book_list,
"page_range": paginator.page_range,
"amount": int(amount),
"paginator": paginator
})
**index.html**
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/3.3.7/css/bootstrap.min.css"
integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
</head>
<body>
<div class="container">
<h4>分页器</h4>
<ul>
{% for book in book_list %}
<li>{{ book.title }} -----{{ book.price }}</li>
{% endfor %}
</ul>
<ul class="pagination" id="pager">
{% if book_list.has_previous %}
<li class="previous"><a href="/index/?page={{ book_list.previous_page_number }}">上一页</a></li>
{% else %}
<li class="previous disabled"><a href="#">上一页</a></li>
{% endif %}
{% for num in paginator.page_range %}
{% if num == currentPage %}
<li class="item active"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% else %}
<li class="item"><a href="/index/?page={{ num }}">{{ num }}</a></li>
{% endif %}
{% endfor %}
{% if book_list.has_next %}
<li class="next"><a href="/index/?page={{ book_list.next_page_number }}">下一页</a></li>
{% else %}
<li class="next disabled"><a href="#">下一页</a></li>
{% endif %}
</ul>
</div>
</body>
</html>
分页器扩展(views.py)
def index(request):
book_list=Book.objects.all()
paginator = Paginator(book_list, 15)
page = request.GET.get('page',1)
currentPage=int(page)
# 如果页数十分多时,换另外一种显示方式
if paginator.num_pages>30:
if currentPage-5<1:
pageRange=range(1,11)
elif currentPage+5>paginator.num_pages:
pageRange=range(currentPage-5,paginator.num_pages+1)
else:
pageRange=range(currentPage-5,currentPage+5)
else:
pageRange=paginator.page_range
try:
print(page)
book_list = paginator.page(page)
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages)
return render(request,"index.html",locals())
分页组件
1.分页的实现与使用
class Pagination(object):
"""自定义分页"""
def __init__(self, current_page, total_count, base_url, params, pre_page_count=10, max_page_count=11):
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page <= 0:
self.current_page = 1
self.current_page = current_page
self.total_count = total_count # 数据总条数
self.pre_page_count = pre_page_count # 每页显示10条数据
max_page_num, div = divmod(total_count, pre_page_count) # 页面上因该显示的最大页码
if div:
max_page_num += 1
self.max_page_num = max_page_num
self.max_page_count = max_page_count # 页面上默认显示11个页码(当前页在中间)
self.half_max_page_count = int((max_page_count-1)/2)
self.base_url = base_url # URL前缀
import copy
params = copy.deepcopy(params) # request.GET
params._mutable = True
# 包含当前列表页面所有的搜索条件
# {source: [2, ], status: [2, ], gender: [2, ], consultant: [1, ], page: [2, ]}
# self.params[page] = 8
# self.params.urlencode()
# source=2&status=2&gender=2&consultant=1&page=8
# href = "/hosts/?source=2&status=2&gender=2&consultant=1&page=8"
# href = "%s?%s" % (self.base_url, self.params.urlencode())
self.params = params
@property
def start(self):
render(self.current_page-1) * self.pre_page_count
@property
def end(self):
return self.current_page * self.pre_page_count
def page_html(self):
# 如果总页数小于等于11
if self.max_page_num <= self.max_page_count:
page_start = 1
page_end = self.max_page_num
else: # 如果总页数大于11
# 如果当前页小于等于5
if self.current_page <= self.half_max_page_count:
page_start = 1
page_end = self.max_page_count
else: # 如果当前页+5大于总页码
if (self.current_page + self.half_max_page_count) > self.max_page_num:
page_end = self.max_page_num
page_start = self.max_page_num - self.max_page_count+1 # 倒着数11个
else:
page_start = self.current_page - self.half_max_page_count
page_end = self.current_page - self.half_max_page_count
page_list = []
# {source:[2,], status:[2], gender:[2],consultant:[1],page:[1]}
# 首页
self.params["page"] = 1
first_page = '<li><a href="%s?%s">首页</a></li>' % (self.base_url, self.params.urlencode(),)
page_list.append(first_page)
# 上一页
self.params["page"] = self.current_page-1
if self.params["page"] < 1:
previous_page = '<li class="disabled"><a href="%s?%s" aria-label="Previous">上一页</span></a></li>' %
(self.base_url, self.params.urlencode())
else:
previous_page = '<li><a href = "%s?%s" aria-label = "Previous" >上一页</span></a></li>' % (
self.base_url, self.params.urlencode())
page_list.append(previous_page)
# 中间页码
for i in range(page_start, page_end + 1):
self.params['page'] = i
if i == self.current_page:
temp = '<li class="active"><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)
else:
temp = '<li><a href="%s?%s">%s</a></li>' % (self.base_url, self.params.urlencode(), i,)
page_list.append(temp)
# 下一页
self.params["page"] = self.current_page + 1
if self.params["page"] > self.max_page_num:
self.params["page"] = self.current_page
next_page = '<li class="disabled"><a href = "%s?%s" aria-label = "Next">下一页</span></a></li >' % (
self.base_url, self.params.urlencode())
else:
next_page = '<li><a href = "%s?%s" aria-label = "Next">下一页</span></a></li>' % (
self.base_url, self.params.urlencode())
page_list.append(next_page)
# 尾页
self.params['page'] = self.max_page_num
last_page = '<li><a href="%s?%s">尾页</a></li>' % (self.base_url, self.params.urlencode(),)
page_list.append(last_page)
return ''.join(page_list)
2.使用
# 自定义分页组件的使用方法:
pager_obj = Pagination(request.GET.get('page',1), len(HOST_LIST), request.path_info,request.GET)
host_list = HOST_LIST[pager_obj.start:pager_obj.end]
html = pager_obj.page_html()
return render(request, 'hosts.html', {'host_list':host_list,"page_html":html})