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)