Django 分页器
分页器
1. 分页器组件介绍
1. 项目数据量大了以后,比如涉及到分页,一页一页的加载显示
2. django中分页器组件,把分页常用的东西,封装到一个类中
3. 实例化得到一个对象,对象里有属性和方法
4. 在页面显示分页数据,需要用到Django分页器组件
from django.core.paginator import Paginator
2. 批量插入数据
def index(request):
for i in range(100):
models.Book.objects.create(name='书籍%s'%i,price=i+1)
book_queryset = models.Book.objects.all()
ll = []
for i in range(100):
book = models.Book(name='书籍%s' % i, price=i + 1)
ll.append(book)
models.Book.objects.bulk_create(ll, 10)
"""
当你想要批量插入数据的时候 使用orm给你提供的bulk_create能够大大的减少操作时间
:param request:
:return:
"""
return render(request, 'index.html',locals())
3. 分页器简单使用
per_page: 每页显示条目数量
count: 数据总个数
num_pages:总页数
page_range:总页数的索引范围,如: (1,10),(1,200)
page: page对象
has_next 是否有下一页
next_page_number 下一页页码
has_previous 是否有上一页
previous_page_number 上一页页码
object_list 分页之后的数据列表
number 当前页
paginator paginator对象
book_list=models.Book.objects.all()
paginator=Paginator(book_list,10)
print(paginator.per_page)
print(paginator.count)
print(paginator.num_pages)
print(paginator.page_range)
page=paginator.page(2)
print(page.has_next())
print(page.next_page_number())
print(page.has_previous())
print(page.previous_page_number())
print(page.object_list)
print(page.number)
class Meta:
ordering=('id', )
4. 视图
def index(request):
page_num_int=int(request.GET.get('page',1))
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 10)
page_range = paginator.page_range
page = paginator.page(page_num_int)
return render(request, 'index.html', {'page_range':page_range,'page':page,'page_num_int':page_num_int})
5. 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<title>Title</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table">
<thead>
<tr>
<th>id</th>
<th>名字</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in page.object_list %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="/?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for page_num in page_range %}
{% if page_num_int == page_num %}
<li class="active"><a href="/?page={{ page_num }}">{{ page_num }}</a></li>
{% else %}
<li><a href="/?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="/?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
</div>
</body>
</html>
6. 分页器的进阶使用
显示左5,右5,总共11个页,
1. 如果总页码大于11
1.1 if 当前页码减5小于1,要生成1到12的列表(顾头不顾尾,共11个页码)
page_range=range(1,12)
1.2 elif 当前页码+5大于总页码,生成当前页码减10,到当前页码加1的列表(顾头不顾尾,共11个页码)
page_range=range(paginator.num_pages-10,paginator.num_pages+1)
1.3 else 生成当前页码-5,到当前页码+6的列表
page_range=range(current_page_num-5,current_page_num+6)
2. 其它情况,生成的列表就是pageinator的page_range
page_range=paginator.page_range
7. 视图
def index(request):
page_num_int = int(request.GET.get('page', 1))
book_list = models.Book.objects.all()
paginator = Paginator(book_list, 1)
if paginator.num_pages > 11:
if page_num_int - 5 < 1:
page_range = range(1, 11)
elif page_num_int + 5 > paginator.num_pages:
page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
else:
page_range = range(page_num_int - 5, page_num_int + 5)
else:
page_range = paginator.page_range
page = paginator.page(page_num_int)
return render(request, 'index.html', {'page_range': page_range, 'page': page, 'page_num_int': page_num_int})
8. 模板
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="stylesheet" href="/static/bootstrap/css/bootstrap.min.css">
<title>Title</title>
</head>
<body>
<div class="container-fluid">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<table class="table">
<thead>
<tr>
<th>id</th>
<th>名字</th>
<th>价格</th>
</tr>
</thead>
<tbody>
{% for book in page.object_list %}
<tr>
<td>{{ book.id }}</td>
<td>{{ book.name }}</td>
<td>{{ book.price }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<div class="text-center">
<nav aria-label="Page navigation">
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="/?page={{ page.previous_page_number }}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% endif %}
{% for page_num in page_range %}
{% if page_num_int == page_num %}
<li class="active"><a href="/?page={{ page_num }}">{{ page_num }}</a></li>
{% else %}
<li><a href="/?page={{ page_num }}">{{ page_num }}</a></li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="/?page={{ page.next_page_number }}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled">
<a href="" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% endif %}
</ul>
</nav>
</div>
</div>
</div>
</div>
</body>
</html>
9. 自定义分页器
"""
django也有内置的分页器模块 但是功能较少代码繁琐不便于使用
所以我们自己自定义我们自己的分页器
"""
1. queryset对象是直接切片操作的
2. 用户到底要访问哪一页 如何确定 url?page=1
current_page = request.GET.get('page',1)
3. 自己规定每页展示多少条数据
per_page_num = 10
4. 切片的起始位置和终止位置
start_page = (current_page - 1)* per_page_num
end_page = current_page * per_page_num
5. 当前数据的总条数
book_queryset.count()
6. 如何确定总共需要多少页才能展示完所有的数据
page_count, more = divmod(all_count,per_page_num)
if more:
page_count += 1
7. 前端模版语法是没有range功能的
8. 针对需要展示的页码需要你自己规划好到底展示多少个页码
当前页减5
当前页加6
你可以给标签价样式从而让选中的页码高亮显示
9. 针对页码小于6的情况 你需要做处理 不能再减
10. 自定义分页器的拷贝及使用
"""
当我们需要使用到非django内置的第三方功能或者组件代码的时候
我们一般情况下会创建一个名为utils文件夹 在该文件夹内对模块进行功能性划分
utils可以在每个应用下创建 具体结合实际情况
我们到了后期封装代码的时候 不再局限于函数
还是尽量朝面向对象去封装
我们自定义的分页器是基于bootstrap样式来的 所以你需要提前导入bootstrap
bootstrap 版本 v3
jQuery 版本 v3
"""
book_queryset = models.Book.objects.all()
current_page = request.GET.get('page',1)
all_count = book_queryset.count()
page_obj = Pagination(current_page=current_page,all_count=all_count)
page_queryset = book_queryset[page_obj.start:page_obj.end]
{% for book_obj in page_queryset %}
<p>{{ book_obj.title }}</p>
<nav aria-label="Page navigation">
</nav>
{% endfor %}
{
{{ page_obj.page_html|safe }}