分页加载
普通实现
向book表添加大量数据
class Book(models.Model):
title = models.CharField(max_length=32)
def __str__(self):
return self.title
class Meta:
db_table = 'book'
if __name__ == '__main__':
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "TestProject.settings")
import django
django.setup()
books = (models.Book(title='图书{}'.format(i)) for i in range(300))
models.Book.objects.bulk_create(books)
template
<div class="container">
<table class="table table-bordered">
<thead>
<tr>
<th>序号</th>
<th>id</th>
<th>书名</th>
</tr>
</thead>
<tbody>
{% for book in book_list %}
<tr>
<td>{{ forloop.counter }}</td>
<td>{{ book.id }}</td>
<td>{{ book.title }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav aria-label="Page navigation">
<ul class="pagination">
{{ html_page|safe }}
</ul>
</nav>
</div>
分页加载具体代码
from app02 import models
from django.shortcuts import render
def books(request):
# 从url中获取当前页码数
current_page = 1
try:
current_page = int(request.GET.get('page'))
except Exception as e:
current_page = 1
# 总数量
total_count = models.Book.objects.count()
# 每页数量
per_count = 10
# 总页数
total_page, more = divmod(total_count, per_count)
if more:
total_page += 1
# 每页显示最大页码数,(左右对称定义奇数)
max_page_num = 11
half_page_num = max_page_num // 2
# 计算当前页面的页码范围
if max_page_num >= total_page:
# 总页码书小于最大显示页码数
start_page = 1
end_page = total_page
elif current_page + half_page_num >= total_page:
# 右边越界
end_page = total_page
start_page = total_page - max_page_num
elif current_page - half_page_num <= 1:
# 左边越界
start_page = 1
end_page = max_page_num
else:
# 正常状态
start_page = current_page - half_page_num
end_page = current_page + half_page_num
start_index = (current_page - 1) * per_count
end_index = current_page * per_count
book_list = models.Book.objects.all()[start_index:end_index]
page_html_list = []
# 加首页页码
first_li = '<li><a href="/books/?page=1">首页</a></li>'
page_html_list.append(first_li)
# 加上一页页码
if current_page == 1:
prev_li = '<li class="disabled"><a href="#"><span aria-hidden="true">«</span></a></li>'
else:
prev_li = '<li><a href="/books/?page={}"><span aria-hidden="true">«</span></a></li>'.format(
current_page - 1)
page_html_list.append(prev_li)
# 加中间页码
for i in range(start_page, end_page + 1):
if i == current_page:
li = '<li class="active"><a href="/books/?page={0}">{0}</a></li>'.format(i)
else:
li = '<li><a href="/books/?page={0}">{0}</a></li>'.format(i)
page_html_list.append(li)
# 加下一页页码
if current_page == total_page:
next_li = '<li class="disabled"><a href="#"><span aria-hidden="true">»</span></a></li>'
else:
next_li = '<li><a href="/books/?page={}"><span aria-hidden="true">»</span></a></li>'.format(
current_page + 1)
page_html_list.append(next_li)
# 加尾页页码
end_li = '<li><a href="/books/?page={}">尾页</a></li>'.format(total_page)
page_html_list.append(end_li)
html_page = ''.join(page_html_list)
return render(request, 'books.html', {'book_list': book_list, 'html_page': html_page})
封装实现
class Page:
def __init__(self, current_page, total_count, base_url, per_page=10, max_page_num=11):
"""
:param current_page:当前页
:param total_count: 总数量
:param base_url: 请求url
:param per_page: 每页数量
:param max_page_num:每页最大页码数
"""
# 当前页
try:
self.current_page = int(current_page)
except Exception as e:
self.current_page = 1
# 每页数量
self.per_page = per_page
# 总页数
total_page, more = divmod(total_count, per_page)
if more:
total_page += 1
self.total_page = total_page
# 最大页码数
self.max_page_num = max_page_num
self.half_page_num = max_page_num // 2
self.base_url = base_url
@property
def start(self):
return (self.current_page - 1) * self.per_page
@property
def end(self):
return self.current_page * self.per_page
def page_html(self):
if self.total_page <= self.max_page_num:
# 总页码数小于最大页码数
start_page = 1
end_page = self.total_page
elif self.current_page + self.half_page_num >= self.total_page:
# 右边越界
end_page = self.total_page
start_page = self.total_page - self.max_page_num
elif self.current_page - self.half_page_num <= 1:
# 左边越界
start_page = 1
end_page = self.max_page_num
else:
# 正常
start_page = self.current_page - self.half_page_num
end_page = self.current_page + self.half_page_num
# 生成页码html
page_html_list = []
# 添加首页页码
first_li = '<li><a href="{}?page=1">首页</a></li>'.format(self.base_url)
page_html_list.append(first_li)
# 添加上一页
if self.current_page == 1:
prev_li = '<li class="disabled"><a href="#"><span aria-hidden="true">«</span></a></li>'
else:
prev_li = '<li><a href="{}?page={}"><span aria-hidden="true">«</span></a></li>'.format(
self.base_url, self.current_page - 1)
page_html_list.append(prev_li)
# 添加中间页码
for i in range(start_page, end_page + 1):
if i == self.current_page:
li = '<li class="active"><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
else:
li = '<li ><a href="{0}?page={1}">{1}</a></li>'.format(self.base_url, i)
page_html_list.append(li)
# 添加下一页
if self.current_page == self.total_page:
next_li = '<li class="disabled"><a href="#"><span aria-hidden="true">»</span></a></li>'
else:
next_li = '<li><a href="{}?page={}"><span aria-hidden="true">»</span></a></li>'.format(
self.base_url, self.current_page + 1)
page_html_list.append(next_li)
# 添加尾页
end_li = '<li><a href="{}?page={}">尾页</a></li>'.format(self.base_url, self.total_page)
page_html_list.append(end_li)
return ''.join(page_html_list)
使用示例:
from utils.Pagination import Page
def books(request):
current_page = int(request.GET.get('page'))
total_count = models.Book.objects.count()
page_obj = Page(current_page, total_count, request.path_info)
book_list = models.Book.objects.all()[page_obj.start:page_obj.end]
page_html = page_obj.page_html()
return render(request, 'books.html', {'book_list': book_list, 'html_page': page_html})
Django 内置分页
from django.core.paginator import Paginator, EmptyPage, PageNotAnInteger
def books(request):
current_page = request.GET.get('page')
paginator = Paginator(models.Book.objects.all(), 10)
"""
paginator.per_page # 每页显示数量
paginator.count # 数据总数
paginator.num_pages # 总页数
paginator.page_range # 页码范围
paginator.page # 页码范围
"""
try:
book_list = paginator.page(current_page)
"""
book_list.has_previous() # 是否有上一页
book_list.has_next() # 是否有下一页
"""
except PageNotAnInteger:
book_list = paginator.page(1)
except EmptyPage:
book_list = paginator.page(paginator.num_pages)
return render(request, 'books.html', {'book_list': book_list})