Django 分页器
- 2022 年 3 月 8 日
- 筆記
- django, Django 分页器
目录
Django 分页器
在页面显示分页数据,需要用到Django分页器组件
先看效果图:
使用分页器需要导入模块
- 导入:
from django.core.paginator import Paginator
方法介绍
Paginator对象:
paginator = Paginator(user_list, 10) # 传入分页数据,和展示的条数
# per_page: 每页显示条目数量
# count: 数据总个数
# num_pages:总页数
# page_range:总页数的索引范围,如: (1,10),(1,200)
# page: page对象
page对象:page=paginator.page(1)
# has_next 是否有下一页
# next_page_number 下一页页码
# has_previous 是否有上一页
# previous_page_number 上一页页码
# object_list 分页之后的数据列表
# number 当前页
# paginator paginator对象
示例
'''urls.py'''
from django.contrib import admin
from django.urls import path
from app01 import views
urlpatterns = [
path('admin/', admin.site.urls),
path('user_list/',views.user_page),
path('delete/',views.delete),
]
'''views.py'''
from django.core.paginator import Paginator
from django.shortcuts import render, redirect
from app01 import models
def user_page(request):
user_page_num = int(request.GET.get('page_num', 1)) # 用户不传页码默认为1
user_list = models.User.objects.all() # 获取所有数据
'''Paginator 对象'''
# 实例化
paginator = Paginator(user_list, 10) # 分页的数据,每页显示十行
# print(paginator.count) # 总条数 500
# print(paginator.num_pages) # 总页数 50
# print(paginator.per_page) # 每页显示条数 10
# print(paginator.page_range) # 生成器,next拿一页 range(1,51)
# print(paginator.page(1)) # page(1)第一页,()内写几可以拿到的页
# 判断页码数和11的关系,布局
'''Page对象'''
try:
page = paginator.page(user_page_num) # 获取当前页
# print(page.has_next()) # 判断有没有下一页 True
# print(page.next_page_number()) # 下一页页码数 3
# print(page.has_previous()) # 判断有没有上一页 True
# print(page.previous_page_number()) # 上一页页码 1
# print(paginator.object_list) # 获取该页的所有数据的对象
except Exception as e:
user_page_num = paginator.num_pages # 如果没有搜索页设置默认数显示最后一页
page = paginator.page(user_page_num) # 没有搜索页显示最后一页
# print(page.number) # 获取当前页码 2
if paginator.num_pages > 11:
# 开头的判断,如果当前页-5小于1,那么显示1,12
if user_page_num - 5 < 1:
page_range = range(1, 12)
# 末尾的判断,如果当前页+5大于总页码数,回退11
elif user_page_num + 5 > paginator.num_pages:
page_range = range(paginator.num_pages - 10, paginator.num_pages + 1)
# 中间当前页-5,+6
else:
page_range = range(user_page_num - 5, user_page_num + 6)
else:
page_range = paginator.page_range # 如果小于11那么就显示少有的对象
return render(request, 'user_page.html', locals())
def delete(request):
del_id = request.GET.get('del_id')
# is_delete = 0
models.User.objects.filter(pk=del_id).delete()
# models.User.objects.filter(pk=del_id).update(is_delete=1)
import time
time.sleep(3)
return redirect('/user_list/')
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<script src="//cdn.bootcdn.net/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<link href="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet">
<script src="//cdn.bootcdn.net/ajax/libs/twitter-bootstrap/3.4.1/js/bootstrap.min.js"></script>
<script src="//unpkg.com/sweetalert/dist/sweetalert.min.js"></script>
</head>
<body>
{#数据#}
<div class="container">
<h1 style="text-align: center">Uesr-Info</h1>
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div>
<table class="table table-striped table-hover">
<thead>
<tr>
<th>id</th>
<th>name</th>
<th>phone</th>
<th>address</th>
<th>action</th>
</tr>
</thead>
<tbody>
{# 获取当前页的所有对象 #}
{% for user in page.object_list %}
<tr>
<td>{{ user.id }}</td>
<td>{{ user.name }}</td>
<td>{{ user.phone }}</td>
<td>{{ user.address }}</td>
<td class="btn btn-danger btn-xs"><a href="/delete/?del_id={{ user.id }}" id="del">删除</a>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
{#分页#}
<nav aria-label="Page navigation" class="text-center">
<ul class="pagination">
{# 判断是否有上一页 #}
{% if page.has_previous %}
<li>
<a href="/user_list/?page_num={{ 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循环拿到页码数 #}
{% for foo in page_range %}
{% if user_page_num == foo %}
<li class="active"><a href="/user_list/?page_num={{ foo }}">{{ foo }}</a></li>
{% else %}
<li><a href="/user_list/?page_num={{ foo }}">{{ foo }}</a></li>
{% endif %}
{% endfor %}
{# 判断是否有下一页 #}
{% if page.has_next %}
<li>
<a href="/user_list/?page_num={{ 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>
</body>
<script>
$('#del').click(function () {
swal({
title: "确定要删除吗?",
text: "删除一条数据",
icon: "warning",
buttons: true,
dangerMode: true,
})
.then((willDelete) => {
if (willDelete) {
swal("删除成功", {
icon: "success",
});
} else {
swal("取消删除");
}
});
})
</script>
</html>
分页器模板
class Pagination(object):
def __init__(self, current_page, all_count, per_page_num=2, pager_count=5):
"""
封装分页相关数据
:param current_page: 当前页
:param all_count: 数据库中的数据总条数
:param per_page_num: 每页显示的数据条数
:param pager_count: 最多显示的页码个数
"""
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page < 1:
current_page = 1
self.current_page = current_page
self.all_count = all_count
self.per_page_num = per_page_num
# 总页码
all_pager, tmp = divmod(all_count, per_page_num)
if tmp:
all_pager += 1
self.all_pager = all_pager
self.pager_count = pager_count
self.pager_count_half = int((pager_count - 1) / 2)
@property
def start(self):
return (self.current_page - 1) * self.per_page_num
@property
def end(self):
return self.current_page * self.per_page_num
def page_html(self):
# 如果总页码 < 11个:
if self.all_pager <= self.pager_count:
pager_start = 1
pager_end = self.all_pager + 1
# 总页码 > 11
else:
# 当前页如果<=页面上最多显示11/2个页码
if self.current_page <= self.pager_count_half:
pager_start = 1
pager_end = self.pager_count + 1
# 当前页大于5
else:
# 页码翻到最后
if (self.current_page + self.pager_count_half) > self.all_pager:
pager_end = self.all_pager + 1
pager_start = self.all_pager - self.pager_count + 1
else:
pager_start = self.current_page - self.pager_count_half
pager_end = self.current_page + self.pager_count_half + 1
page_html_list = []
# 添加前面的nav和ul标签
page_html_list.append('''
<nav aria-label='Page navigation>'
<ul class='pagination'>
''')
first_page = '<li><a href="?page=%s">首页</a></li>' % (1)
page_html_list.append(first_page)
if self.current_page <= 1:
prev_page = '<li class="disabled"><a href="#">上一页</a></li>'
else:
prev_page = '<li><a href="?page=%s">上一页</a></li>' % (self.current_page - 1,)
page_html_list.append(prev_page)
for i in range(pager_start, pager_end):
if i == self.current_page:
temp = '<li class="active"><a href="?page=%s">%s</a></li>' % (i, i,)
else:
temp = '<li><a href="?page=%s">%s</a></li>' % (i, i,)
page_html_list.append(temp)
if self.current_page >= self.all_pager:
next_page = '<li class="disabled"><a href="#">下一页</a></li>'
else:
next_page = '<li><a href="?page=%s">下一页</a></li>' % (self.current_page + 1,)
page_html_list.append(next_page)
last_page = '<li><a href="?page=%s">尾页</a></li>' % (self.all_pager,)
page_html_list.append(last_page)
# 尾部添加标签
page_html_list.append('''
</nav>
</ul>
''')
return ''.join(page_html_list)