1、概念
每一页的数据量我们可以自定义,比如每页我们要求只显示 10 条数据。
2、功能
比如有数据:1, 2, 3, …, 100
假设我们规定:
页码(page)= 1
每一页(per_page)= 10
页码(page) | 数据范围(per_page) | 下标范围 | 切片范围 |
---|---|---|---|
1 | 1 ~ 10 | 0 ~ 9 | [ 0 : 10 ] |
2 | 11 ~ 20 | 10 ~ 19 | [ 10 : 20 ] |
3 | 21 ~ 30 | 20 ~ 39 | [ 20 : 30 ] |
… | … | … | … |
n | … | … | [ (page-1) * per_page : page * per_page ] |
3、案例
实现功能:根据数据量与我们规定的每页数据量自动创建页码按钮,当点击页面对应的页码按钮时,跳转到对应的页码数据。
先创建一百多个测试数据:
视图
import math
from App.models import *
from django.shortcuts import render, HttpResponse
def paginate(request, page=1):
# 页码:page
# 每页数量:per_page
per_page = 10
# 获取数据库PersonModel的所有表数据
persons = PersonModel.objects.all()
# 对获取的表数据切片操作
persons = persons[(page-1) * per_page:page * per_page]
# 总页数
total = PersonModel.objects.count() # 数据总条数
total_page = math.ceil(total / per_page) # 总页数(即总条数/每页条数)math.ceil向上取整,即返回大于或等于该数字的最小整数。如果传入的参数已经是整数,则返回该整数本身(如3.5则返回4(即大于3.5的数的最小整数),如7则返回7)。
pages = range(1, total_page+1) # 为什么要转换一下?因为传到模板的数据必须是一个字典,且字典的 values 必须是一个序列
# 将切片的数据传入模板进行渲染
return render(request, 'paginate.html', {'persons':persons, 'pages': pages})
路由
from django.contrib import admin
from django.urls import path
from App.views import *
urlpatterns = [
path('admin/', admin.site.urls),
path('add/', add_person),
path('del/', del_person),
path('update/', update_person),
path('get/', get_person),
path('paginate/<int:page>/', paginate, name='paginate'),
]
模板
paginate.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手动分页</title>
<style>
ul {
list-style: none;
padding: 0;
}
.bts li {
float: left;
margin: 5px;
}
hr {
clear: both;
}
</style>
</head>
<body>
<h2>手动分页功能</h2>
<hr>
<ul class="bts">
{% for page in pages %}
<li>
<a href="{% url 'paginate' page %}"><button>{{ page }}</button></a>
</li>
{% endfor %}
</ul>
<hr>
<ul>
{% for person in persons %}
<li>{{ person.name }} - {{ person.age }}</li>
{% endfor %}
</ul>
</body>
</html>
验证
当点击 15 这个页码按钮时,就会跳到数据的第 15 页的数据。
上面的分页是手动进行的,需要我们手动写功能。当然我们也可以使用 Django 中的分页器进行自动分页,使用时需导入 Paginator 模块。接下来,将使用分页器实现与手动分页功能完全一致的分页方法。
1、视图
import math
from App.models import *
from django.shortcuts import render, HttpResponse
from django.core.paginator import Paginator
def paginate2(request, page=1):
# 每页数量
per_page = 10
all_date = PersonModel.objects.all()
# 分页器对象
paginator = Paginator(all_date, per_page) # 获取所有用户数据,并根据每页显示10条用户数据进行分页
persons = paginator.page(page) # 获取指定page页的数据
pages = paginator.page_range # 页码范围,可进行循环遍历
return render(request, 'paginate2.html', {'persons': persons, 'pages': pages})
2、路由
from django.contrib import admin
from django.urls import path
from App.views import *
urlpatterns = [
path('admin/', admin.site.urls),
path('add/', add_person),
path('del/', del_person),
path('update/', update_person),
path('get/', get_person),
path('paginate/<int:page>/', paginate, name='paginate'),
path('paginate2/<int:page>/', paginate2, name='paginate2'),
]
3、模板
paginate2.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>手动分页</title>
<style>
ul {
list-style: none;
padding: 0;
}
.bts li {
float: left;
margin: 5px;
}
hr {
clear: both;
}
</style>
</head>
<body>
<h2>手动分页功能</h2>
<hr>
<ul class="bts">
{% for page in pages %}
<li>
<a href="{% url 'paginate2' page %}"><button>{{ page }}</button></a>
</li>
{% endfor %}
</ul>
<hr>
<ul>
{% for person in persons %}
<li>{{ person.name }} - {{ person.age }}</li>
{% endfor %}
</ul>
</body>
</html>
4、验证
—END