Flask Paginate實(shí)現(xiàn)表格分頁(yè)的使用示例
flask_paginate 是 Flask 框架的一個(gè)分頁(yè)擴(kuò)展,用于處理分頁(yè)相關(guān)的功能。它可以幫助你在 Flask Web 應(yīng)用程序中實(shí)現(xiàn)分頁(yè)功能,讓用戶(hù)可以瀏覽大量數(shù)據(jù)的不同部分。本篇博文重點(diǎn)講述在Web開(kāi)發(fā)中,用paginate把所有數(shù)據(jù)進(jìn)行分頁(yè)展示,首先通過(guò)運(yùn)用第三方庫(kù)實(shí)現(xiàn)后端分頁(yè),然后再自己編寫(xiě)一個(gè)分頁(yè)類(lèi)實(shí)現(xiàn)。
flask_sqlalchemy
Flask-SQLAlchemy 是 Flask 框架的一個(gè)擴(kuò)展,提供了對(duì) SQL 數(shù)據(jù)庫(kù)的集成支持。它基于 SQLAlchemy 構(gòu)建,簡(jiǎn)化了在 Flask 應(yīng)用中使用數(shù)據(jù)庫(kù)的操作。
安裝 Flask-SQLAlchemy:
pip install Flask-SQLAlchemy
Flask-SQLAlchemy的使用很簡(jiǎn)單,如下是一些簡(jiǎn)單的用法;
from flask import Flask
from sqlalchemy import not_,or_,and_,desc
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
# url的格式為:數(shù)據(jù)庫(kù)的協(xié)議://用戶(hù)名:密碼@ip地址:端口號(hào)(默認(rèn)可以不寫(xiě))/數(shù)據(jù)庫(kù)名
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///:memory:"
# 為了解決控制臺(tái)的提示
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
# 創(chuàng)建數(shù)據(jù)庫(kù)的操作對(duì)象
db = SQLAlchemy(app)
# 創(chuàng)建規(guī)則表
class RoleDB(db.Model):
__tablename__ = "role"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
# 增加反查外鍵關(guān)聯(lián)到UserDB
users = db.relationship('UserDB', backref="role")
# 當(dāng)調(diào)用 Role.query.all() 會(huì)觸發(fā)輸出
def __repr__(self):
return "Role: %s | %s" % (self.id, self.name)
# 創(chuàng)建用戶(hù)表
class UserDB(db.Model):
__tablename__ = "user"
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(16), unique=True)
email = db.Column(db.String(32), unique=True)
password = db.Column(db.String(16))
# 關(guān)聯(lián)到RuleDB表中的ID上面
role_id = db.Column(db.Integer, db.ForeignKey("role.id"))
# 當(dāng)調(diào)用 RoleDB.query.all() 會(huì)觸發(fā)輸出
def __repr__(self):
return "User: %s | %s | %s | %s" % (self.id, self.name, self.password, self.role_id)
@app.route('/')
def index():
# 此處查詢(xún)會(huì)走類(lèi)內(nèi) __repr__ 輸出
print("查詢(xún)所有用戶(hù)數(shù)據(jù): ", UserDB.query.all())
print("查詢(xún)所有規(guī)則數(shù)據(jù): ", RoleDB.query.all())
print("查詢(xún)有多少個(gè)用戶(hù): ", UserDB.query.count())
print("查詢(xún)第一個(gè)用戶(hù): ", UserDB.query.first())
# 查詢(xún)過(guò)濾器
print("查詢(xún)第一條: ", UserDB.query.get(1))
print("查詢(xún)過(guò)濾器(類(lèi)名+屬性名): ", UserDB.query.filter(UserDB.id == 4).first())
print("查詢(xún)過(guò)濾器(屬性名): ", UserDB.query.filter_by(id=4).first())
# 查詢(xún)名字結(jié)尾字符為g的所有數(shù)據(jù) [開(kāi)始/包含]
print(UserDB.query.filter(UserDB.name.endswith("g")).all())
print(UserDB.query.filter(UserDB.name.contains("g")).all())
# 查詢(xún)名字不等于wang的所有數(shù)據(jù) [2種方式]
print(UserDB.query.filter(not_(UserDB.name == "wang")).all())
print(UserDB.query.filter(UserDB.name != "wang").all())
# 查詢(xún) [名字和郵箱] 都以li開(kāi)頭的所有數(shù)據(jù) [2種方式]
print(UserDB.query.filter(and_(UserDB.name.startswith("li"),UserDB.email.startswith("li"))).all())
print(UserDB.query.filter(UserDB.name.startswith("li"), UserDB.email.startswith("li")).all())
# 查詢(xún)password是 123456 或者 email 以 lyshark.com 結(jié)尾的所有數(shù)據(jù)
print(UserDB.query.filter(or_(UserDB.password=='123456', UserDB.email.endswith('lyshark.com'))).all())
# 查詢(xún)id為 [1, 3, 5, 7, 9] 的用戶(hù)列表
print(UserDB.query.filter(UserDB.id.in_([1, 3, 5, 7, 9])).all())
# 查詢(xún)name為liu的角色數(shù)據(jù):關(guān)系引用
print(UserDB.query.filter_by(name="liu").first().role.name)
# 查詢(xún)所有用戶(hù)數(shù)據(jù) 并以郵箱排序 [升序/降序]
print("升序: ", UserDB.query.order_by("email").all())
print("降序: ", UserDB.query.order_by(desc("email")).all())
# 查詢(xún)第2頁(yè)的數(shù)據(jù),每頁(yè)只顯示3條數(shù)據(jù)
pages = UserDB.query.paginate(2,3,False)
print("查詢(xún)結(jié)果: {} 總頁(yè)數(shù): {} 當(dāng)前頁(yè)數(shù): {}".format(pages.items,pages.pages,pages.page))
# 完整查詢(xún)調(diào)用寫(xiě)法
ref = db.session.query(UserDB).filter(UserDB.name == "wang").all()
print(ref)
return "success"
if __name__ == "__main__":
# 初始化數(shù)據(jù)表
db.drop_all()
db.create_all()
# 插入兩個(gè)規(guī)則記錄
role_admin = RoleDB(name="admin")
db.session.add(role_admin)
role_lyshark = RoleDB(name="lyshark")
db.session.add(role_lyshark)
db.session.commit()
try:
ua = UserDB(name='wang', email='wang@163.com', password='123456', role_id=role_admin.id)
ub = UserDB(name='zhang', email='zhang@189.com', password='201512', role_id=role_lyshark.id)
uc = UserDB(name='chen', email='chen@126.com', password='987654', role_id=role_lyshark.id)
ud = UserDB(name='zhou', email='zhou@163.com', password='456789', role_id=role_admin.id)
ue = UserDB(name='tang', email='tang@lyshark.com', password='158104', role_id=role_lyshark.id)
uf = UserDB(name='wu', email='wu@gmail.com', password='5623514', role_id=role_lyshark.id)
ug = UserDB(name='qian', email='qian@gmail.com', password='1543567', role_id=role_admin.id)
uh = UserDB(name='liu', email='liu@lyshark.com', password='867322', role_id=role_admin.id)
ui = UserDB(name='li', email='li@163.com', password='4526342', role_id=role_lyshark.id)
uj = UserDB(name='sun', email='sun@163.com', password='235523', role_id=role_lyshark.id)
db.session.add_all([ua, ub, uc, ud, ue, uf, ug, uh, ui, uj])
db.session.commit()
except Exception as e:
# 插入失敗自動(dòng)回滾
db.session.rollback()
raise e
app.run(debug=True)
flask_sqlalchemy 分頁(yè)組件
Flask-SQLAlchemy 分頁(yè)插件為 Flask 應(yīng)用提供了便捷而強(qiáng)大的分頁(yè)功能,通過(guò) paginate() 方法返回的 Pagination 類(lèi)對(duì)象,開(kāi)發(fā)者能夠輕松實(shí)現(xiàn)對(duì)大型數(shù)據(jù)集的分頁(yè)展示。該插件基于 Flask-SQLAlchemy 擴(kuò)展構(gòu)建,簡(jiǎn)化了在 Flask 應(yīng)用中進(jìn)行數(shù)據(jù)庫(kù)查詢(xún)的分頁(yè)操作。通過(guò)靈活的配置選項(xiàng),開(kāi)發(fā)者可以高效地管理和展示數(shù)據(jù),提升用戶(hù)體驗(yàn),是構(gòu)建數(shù)據(jù)驅(qū)動(dòng) Web 應(yīng)用的重要利器。本文將深入介紹 Flask-SQLAlchemy 分頁(yè)插件的基本使用方法以及常見(jiàn)配置選項(xiàng),幫助開(kāi)發(fā)者快速上手并充分發(fā)揮其強(qiáng)大的分頁(yè)功能。
前端部分使用bootstrap實(shí)現(xiàn)分頁(yè)組件,新建前端index.html文件,代碼如下;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
</head>
<body>
<div class="box box-primary">
<div class="box-body table-responsive no-padding">
<table class="table table-sm table-hover">
<thread>
<tr class="table-success">
<th>id</th>
<th>name</th>
<th>email</th>
<th>password</th>
</tr>
</thread>
<tbody>
{% for item in page_data.items %}
<tr class="table-primary">
<td>{{ item.id }}</td>
<td>{{ item.name }}</td>
<td>{{ item.email }}</td>
<td>{{ item.password }}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
<div class="box-footer clearfix">
<nav class="d-flex justify-content-center" aria-label="Page navigation example">
{% if page_data %}
<ul class="pagination">
<li class="page-item"><a class="page-link" href="./1" rel="external nofollow" >首頁(yè)</a></li>
{% if page_data.has_prev %}
<li class="page-item"><a class="page-link" href="{{ page_data.prev_num }}" rel="external nofollow" >上一頁(yè)</a></li>
{% else %}
<li class="page-item" class="disabled"><a class="page-link" href="#" rel="external nofollow" rel="external nofollow" >上一頁(yè)</a></li>
{% endif %}
<!--
{% for item in page_data.iter_pages() %}
{% if item == page_data.page %}
<li class="page-item active"><a class="page-link" href="{{ item }}" rel="external nofollow" rel="external nofollow" >{{ item }}</a></li>
{% else %}
<li class="page-item"><a class="page-link" href="{{ item }}" rel="external nofollow" rel="external nofollow" >{{ item }}</a></li>
{% endif %}
{% endfor %}
-->
<!-- 當(dāng)前頁(yè)的頁(yè)碼/總頁(yè)碼 -->
<p>{{ page_data.page }}</p> / <p>{{ page_data.pages }}</p>
{% if page_data.has_next %}
<li class="page-item"><a class="page-link" href="{{ page_data.next_num }}" rel="external nofollow" >下一頁(yè)</a></li>
{% else %}
<li class="page-item" class="disabled"><a class="page-link" href="#" rel="external nofollow" rel="external nofollow" >下一頁(yè)</a></li>
{% endif %}
<li class="page-item"><a class="page-link" href="{{ page_data.pages }}" rel="external nofollow" >尾頁(yè)</a></li>
</ul>
{% endif %}
</nav>
</div>
</div>
</body>
</html>
使用組件內(nèi)的過(guò)濾器分頁(yè)是非常簡(jiǎn)單的一件事,只需要調(diào)用參數(shù)后返回,后端app.py代碼如下;
from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__, template_folder="./tempate",static_folder="./tempate")
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
# 設(shè)置每次請(qǐng)求結(jié)束后會(huì)自動(dòng)提交數(shù)據(jù)庫(kù)的改動(dòng)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 查詢(xún)時(shí)顯示原始SQL語(yǔ)句
app.config['SQLALCHEMY_ECHO'] = False
# 創(chuàng)建數(shù)據(jù)庫(kù)的操作對(duì)象
db = SQLAlchemy(app)
# 創(chuàng)建用戶(hù)表
class UserDB(db.Model):
__tablename__="user"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
email = db.Column(db.String(32))
password = db.Column(db.String(32))
def __init__(self,name,email,password):
self.name = name
self.email = email
self.password = password
def __repr_(self):
return 'User %s'%self.name
@app.route("/")
def index():
return "<script>window.location.href='./page/1'</script>"
@app.route("/page/<int:page_number>")
def page(page_number=None):
if page_number is None:
page_number = 1
page = db.session.query(UserDB).paginate(page=page_number,per_page=10,max_per_page=15)
return render_template("index.html", page_data = page)
if __name__ == "__main__":
# 初始化數(shù)據(jù)表
db.drop_all()
db.create_all()
try:
ua = UserDB(name='wang', email='wang@163.com', password='123456')
ub = UserDB(name='zhang', email='zhang@189.com', password='201512')
uc = UserDB(name='chen', email='chen@126.com', password='987654')
ud = UserDB(name='zhou', email='zhou@163.com', password='456789')
ue = UserDB(name='tang', email='tang@lyshark.com', password='158104')
uf = UserDB(name='wu', email='wu@gmail.com', password='5623514')
ug = UserDB(name='qian', email='qian@gmail.com', password='1543567')
uh = UserDB(name='liu', email='liu@lyshark.com', password='867322')
ui = UserDB(name='li', email='li@163.com', password='4526342')
uj = UserDB(name='sun', email='sun@163.com', password='235523')
db.session.add_all([ua, ub, uc, ud, ue, uf, ug, uh, ui, uj,uj,uj,uj,uj,uj,uj,uj,uj])
db.session.commit()
except Exception as e:
# 插入失敗自動(dòng)回滾
db.session.rollback()
raise e
app.run(debug=True)
flask_paginate 分頁(yè)組件
Flask-Paginate 是 Flask 框架中的一個(gè)重要插件,為開(kāi)發(fā)者提供了便捷而靈活的分頁(yè)解決方案。通過(guò)結(jié)合 Flask 官方的分頁(yè)部件,這個(gè)插件能夠輕松地實(shí)現(xiàn)對(duì)大量數(shù)據(jù)的分頁(yè)展示,為用戶(hù)提供更友好的瀏覽體驗(yàn)。本文將深入介紹 Flask-Paginate 的核心功能、使用方法以及與數(shù)據(jù)庫(kù)查詢(xún)的協(xié)同操作,幫助開(kāi)發(fā)者更好地利用這一工具來(lái)優(yōu)化 Web 應(yīng)用的分頁(yè)展示。
前端部分使用bootstrap實(shí)現(xiàn)分頁(yè)組件,新建前端index.html文件,代碼如下;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
</head>
<body>
<table class="table table-sm table-hover">
<thead>
<tr class="table-success">
<th>序號(hào)</th>
<th>用戶(hù)ID</th>
<th>用戶(hù)名稱(chēng)</th>
<th>用戶(hù)郵箱</th>
<th>用戶(hù)密碼</th>
</tr>
</thead>
<tbody>
{% for article in articles %}
<tr class="table-primary">
<td>{{ loop.index }}</td>
<td>{{ article.id }}</td>
<td>{{ article.name }}</td>
<td>{{ article.email }}</td>
<td>{{ article.password }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<nav class="d-flex justify-content-center" aria-label="Page navigation example">
<ul class="pagination">
<li class="page-item"><a class="page-link" href="./page=1" rel="external nofollow" rel="external nofollow" >首頁(yè)</a></li>
{% if pagination.has_prev %}
<li class="page-item"><a class="page-link" href="./page={{ prve_num }}" rel="external nofollow" >上一頁(yè)</a></li>
{% endif %}
<!--獲取當(dāng)前列表,并全部填充到這里-->
{% for item in pageRange %}
<!--判斷如果是當(dāng)前頁(yè)則直接標(biāo)號(hào)為藍(lán)色高亮-->
{% if item == currentPage %}
<li class="page-item active"><a class="page-link" href="./page={{ item }}" rel="external nofollow" rel="external nofollow" >{{ item }}</a></li>
<!--否則的話(huà),就直接接收參數(shù)填充-->
{% else %}
<li class="page-item"><a class="page-link" href="./page={{ item }}" rel="external nofollow" rel="external nofollow" >{{ item }}</a></li>
{% endif %}
{% endfor %}
{% if next_end %}
<li class="page-item"><a class="page-link" href="./page={{ next_num }}" rel="external nofollow" >下一頁(yè)</a></li>
{% endif %}
<li class="page-item"><a class="page-link" href="./page={{ PageCount }}" rel="external nofollow" >尾頁(yè)</a></li>
</ul>
</nav>
<div style="text-align: center;" class="alert alert-dark">
統(tǒng)計(jì): {{ pagination.page }}/{{ PageCount }} 共查詢(xún)到:{{ pagination.total }} 條數(shù)據(jù) 頁(yè)碼列表:{{ pageRange }}
</div>
</body>
</html>
后端就是對(duì)請(qǐng)求的響應(yīng),前端用戶(hù)通過(guò)GET方式訪問(wèn),后端獲得用戶(hù)頁(yè)面數(shù),查詢(xún)后動(dòng)態(tài)展示出來(lái)即可。
from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
from flask_paginate import Pagination,get_page_parameter
import math
app = Flask(__name__, template_folder="./tempate",static_folder="./tempate")
# url的格式為:數(shù)據(jù)庫(kù)的協(xié)議://用戶(hù)名:密碼@ip地址:端口號(hào)(默認(rèn)可以不寫(xiě))/數(shù)據(jù)庫(kù)名
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
# 設(shè)置每次請(qǐng)求結(jié)束后會(huì)自動(dòng)提交數(shù)據(jù)庫(kù)的改動(dòng)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 查詢(xún)時(shí)顯示原始SQL語(yǔ)句
app.config['SQLALCHEMY_ECHO'] = False
# 創(chuàng)建數(shù)據(jù)庫(kù)的操作對(duì)象
db = SQLAlchemy(app)
# 創(chuàng)建用戶(hù)表
class UserDB(db.Model):
__tablename__="user"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
email = db.Column(db.String(32))
password = db.Column(db.String(32))
def __init__(self,name,email,password):
self.name = name
self.email = email
self.password = password
def __repr_(self):
return 'User %s'%self.name
@app.route("/")
def index():
return """<script>window.location.href="./page=1" rel="external nofollow" rel="external nofollow" </script>"""
@app.route("/page=<int:id>")
def GetPages(id):
# 默認(rèn)每頁(yè)顯示10個(gè)元素
PER_PAGE = 10
total = db.session.query(UserDB).count()
print("總記錄 {} 條".format(total))
currentPage = request.args.get(get_page_parameter(),type=int,default=int(id))
print("當(dāng)前頁(yè)碼ID為 {}".format(currentPage))
start = (currentPage-1)*PER_PAGE # 分頁(yè)起始位置
end = start+PER_PAGE # 分頁(yè)結(jié)束位置
print("起始位置 {} 結(jié)束位置 {}".format(start,end))
prev_num = int(currentPage)-1
next_num = int(currentPage)+1
print("上一頁(yè)頁(yè)碼 {} 下一頁(yè)頁(yè)碼 {}".format(prev_num,next_num))
# 計(jì)算出需要切割的頁(yè)數(shù)
page_count = math.ceil(total/PER_PAGE)
print("切割頁(yè)數(shù) {}".format(page_count))
pagination = Pagination(page=currentPage,total=total)
# 執(zhí)行數(shù)據(jù)庫(kù)切片
articles = db.session.query(UserDB).slice(start,end)
# 判斷,如果next_end大于總數(shù)說(shuō)明到最后了
if currentPage>=math.ceil(total/PER_PAGE):
# 那么我們就將next_end設(shè)置為0,前端就不執(zhí)行顯示了
next_end=0
else:
next_end=1
# -------------------------------------------------
# 此頁(yè)面是擴(kuò)展部分,用于生成當(dāng)前頁(yè)碼,并填充到前端
# 如果總頁(yè)數(shù)小于15則一次性生成頁(yè)碼即可
if page_count < 15:
pageRange = range(1,page_count+1)
# 總頁(yè)數(shù)大于15則需要分情況生成
elif page_count > 15:
# 說(shuō)明是第一頁(yè)
if currentPage-5 < 1:
pageRange = range(1,11)
# 說(shuō)明是最后一頁(yè)
elif currentPage+5 > page_count:
pageRange = range(currentPage-5,page_count)
# 說(shuō)明是中間頁(yè)
else:
pageRange = range(currentPage-5,currentPage+5)
# 如果都不是則返回總數(shù)
else:
pageRange = page_count
print("生成的當(dāng)前頁(yè)碼: {}".format(pageRange))
context = {
'pagination': pagination,
'articles': articles,
'prve_num': prev_num,
'next_num': next_num,
'PageCount': page_count,
'pageRange': pageRange,
'next_end': next_end,
"currentPage": currentPage
}
return render_template('index.html',**context)
if __name__ == "__main__":
db.drop_all()
db.create_all()
try:
ua = UserDB(name='wang', email='wang@163.com', password='123456')
ub = UserDB(name='zhang', email='zhang@189.com', password='201512')
uc = UserDB(name='chen', email='chen@126.com', password='987654')
ud = UserDB(name='zhou', email='zhou@163.com', password='456789')
ue = UserDB(name='tang', email='tang@lyshark.com', password='158104')
uf = UserDB(name='wu', email='wu@gmail.com', password='5623514')
ug = UserDB(name='qian', email='qian@gmail.com', password='1543567')
uh = UserDB(name='liu', email='liu@lyshark.com', password='867322')
ui = UserDB(name='li', email='li@163.com', password='4526342')
uj = UserDB(name='sun', email='sun@163.com', password='235523')
db.session.add_all([ua, ub, uc, ud, ue, uf, ug, uh, ui, uj,uj,uj,uj,uj,uj,uj,uj,uj])
db.session.commit()
except Exception as e:
# 插入失敗自動(dòng)回滾
db.session.rollback()
raise e
app.run(debug=True)
Pagination 自寫(xiě)分頁(yè)器
前端部分使用bootstrap實(shí)現(xiàn)分頁(yè)組件,新建前端index.html文件,代碼如下;
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" rel="external nofollow" rel="external nofollow" rel="external nofollow" >
</head>
<body>
<table class="table table-sm table-hover">
<thead>
<tr class="table-success">
<th>用戶(hù)ID</th>
<th>用戶(hù)名稱(chēng)</th>
<th>用戶(hù)郵箱</th>
<th>用戶(hù)密碼</th>
</tr>
</thead>
<tbody>
{% for article in articles %}
<tr class="table-primary">
<td>{{ article.id }}</td>
<td>{{ article.name }}</td>
<td>{{ article.email }}</td>
<td>{{ article.password }}</td>
</tr>
{% endfor %}
</tbody>
</table>
<!--輸出頁(yè)碼范圍-->
<nav class="d-flex justify-content-center" aria-label="Page navigation example">
<ul class="pagination">
{{ html|safe }}
</ul>
</nav>
</body>
</html>
首先需要?jiǎng)?chuàng)建一個(gè)pager.py文件,里面包含一個(gè)Pagination分頁(yè)類(lèi)部件。
import copy
from urllib.parse import urlencode
class Pagination(object):
def __init__(self,current_page,total_count,base_url,params,per_page_count=10,max_pager_count=11):
try:
current_page = int(current_page)
except Exception as e:
current_page = 1
if current_page <=0:
current_page = 1
self.current_page = current_page
# 數(shù)據(jù)總條數(shù)
self.total_count = total_count
# 每頁(yè)顯示10條數(shù)據(jù)
self.per_page_count = per_page_count
# 頁(yè)面上應(yīng)該顯示的最大頁(yè)碼
max_page_num, div = divmod(total_count, per_page_count)
if div:
max_page_num += 1
self.max_page_num = max_page_num
# 頁(yè)面上默認(rèn)顯示11個(gè)頁(yè)碼(當(dāng)前頁(yè)在中間)
self.max_pager_count = max_pager_count
self.half_max_pager_count = int((max_pager_count - 1) / 2)
# URL前綴
self.base_url = base_url
# request.GET
params = copy.deepcopy(params)
# params._mutable = True
get_dict = params.to_dict()
# 包含當(dāng)前列表頁(yè)面所有的搜/索條件
self.params = get_dict
@property
def start(self):
return (self.current_page - 1) * self.per_page_count
@property
def end(self):
return self.current_page * self.per_page_count
def page_html(self):
# 如果總頁(yè)數(shù) <= 11
if self.max_page_num <= self.max_pager_count:
pager_start = 1
pager_end = self.max_page_num
# 如果總頁(yè)數(shù) > 11
else:
# 如果當(dāng)前頁(yè) <= 5
if self.current_page <= self.half_max_pager_count:
pager_start = 1
pager_end = self.max_pager_count
else:
# 當(dāng)前頁(yè) + 5 > 總頁(yè)碼
if (self.current_page + self.half_max_pager_count) > self.max_page_num:
pager_end = self.max_page_num
pager_start = self.max_page_num - self.max_pager_count + 1 #倒這數(shù)11個(gè)
else:
pager_start = self.current_page - self.half_max_pager_count
pager_end = self.current_page + self.half_max_pager_count
page_html_list = []
# 首頁(yè)
self.params['page'] = 1
first_page = '<li class="page-item"><a class="page-link" href="%s?%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >首頁(yè)</a></li>' % (self.base_url,urlencode(self.params),)
page_html_list.append(first_page)
# 上一頁(yè)
self.params["page"] = self.current_page - 1
if self.params["page"] < 1:
pervious_page = '<li class="page-item" class="disabled"><a class="page-link" \
href="%s?%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" aria-label="Previous">上一頁(yè)</span></a></li>' % (self.base_url, urlencode(self.params))
else:
pervious_page = '<li class="page-item"><a class="page-link" href = "%s?%s" \
aria-label = "Previous" >上一頁(yè)</span></a></li>' % ( self.base_url, urlencode(self.params))
page_html_list.append(pervious_page)
# 中間頁(yè)碼
for i in range(pager_start, pager_end + 1):
self.params['page'] = i
if i == self.current_page:
temp = '<li class="page-item active" class="active"><a class="page-link" \
href="%s?%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >%s</a></li>' % (self.base_url,urlencode(self.params), i,)
else:
temp = '<li class="page-item"><a class="page-link" \
href="%s?%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >%s</a></li>' % (self.base_url,urlencode(self.params), i,)
page_html_list.append(temp)
# 下一頁(yè)
self.params["page"] = self.current_page + 1
if self.params["page"] > self.max_page_num:
self.params["page"] = self.current_page
next_page = '<li class="page-item" class="disabled"><a class="page-link" \
href = "%s?%s" aria-label = "Next">下一頁(yè)</span></a></li >' % (self.base_url, urlencode(self.params))
else:
next_page = '<li class="page-item"><a class="page-link" href = "%s?%s" \
aria-label = "Next">下一頁(yè)</span></a></li>' % (self.base_url, urlencode(self.params))
page_html_list.append(next_page)
# 尾頁(yè)
self.params['page'] = self.max_page_num
last_page = '<li class="page-item"><a class="page-link" href="%s?%s" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >尾頁(yè)</a></li>' % (self.base_url, urlencode(self.params),)
page_html_list.append(last_page)
return ''.join(page_html_list)
主函數(shù)main.py則直接import Pagination導(dǎo)入分頁(yè)類(lèi),然后調(diào)用Pagination函數(shù)即可實(shí)現(xiàn)分頁(yè)了。
from flask import Flask,render_template,request
from flask_sqlalchemy import SQLAlchemy
from pager import Pagination
app = Flask(__name__, template_folder="./tempate",static_folder="./tempate")
app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db"
# 設(shè)置每次請(qǐng)求結(jié)束后會(huì)自動(dòng)提交數(shù)據(jù)庫(kù)的改動(dòng)
app.config['SQLALCHEMY_COMMIT_ON_TEARDOWN'] = True
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
# 查詢(xún)時(shí)顯示原始SQL語(yǔ)句
app.config['SQLALCHEMY_ECHO'] = False
# 創(chuàng)建數(shù)據(jù)庫(kù)的操作對(duì)象
db = SQLAlchemy(app)
# 創(chuàng)建用戶(hù)表
class UserDB(db.Model):
__tablename__="user"
id = db.Column(db.Integer,primary_key=True)
name = db.Column(db.String(32))
email = db.Column(db.String(32))
password = db.Column(db.String(32))
def __init__(self,name,email,password):
self.name = name
self.email = email
self.password = password
def __repr_(self):
return 'User %s'%self.name
@app.route("/")
def index():
total = db.session.query(UserDB).count()
print("查詢(xún)總記錄數(shù): {}".format(total))
page_number = request.args.get("page", 1)
print("當(dāng)前傳入頁(yè)碼: {}".format(page_number))
# 分頁(yè)類(lèi) [ Pagination(傳入頁(yè)碼/總記錄數(shù)/分頁(yè)URL前綴/傳入數(shù)據(jù)params/每頁(yè)顯示數(shù)/最大顯示頁(yè)碼 )]
Page = Pagination(page_number, total, request.path, request.args, per_page_count=10, max_pager_count=15)
# 對(duì)數(shù)據(jù)切片
index = db.session.query(UserDB)[Page.start:Page.end]
print("頁(yè)面切片: {}".format(index))
# 渲染頁(yè)面
html = Page.page_html()
print("渲染頁(yè)碼頁(yè)面: {}".format(html))
return render_template("index.html",articles=index,html=html)
if __name__ == "__main__":
# 初始化數(shù)據(jù)表
db.drop_all()
db.create_all()
try:
ua = UserDB(name='wang', email='wang@163.com', password='123456')
ub = UserDB(name='zhang', email='zhang@189.com', password='201512')
uc = UserDB(name='chen', email='chen@126.com', password='987654')
ud = UserDB(name='zhou', email='zhou@163.com', password='456789')
ue = UserDB(name='tang', email='tang@lyshark.com', password='158104')
uf = UserDB(name='wu', email='wu@gmail.com', password='5623514')
ug = UserDB(name='qian', email='qian@gmail.com', password='1543567')
uh = UserDB(name='liu', email='liu@lyshark.com', password='867322')
ui = UserDB(name='li', email='li@163.com', password='4526342')
uj = UserDB(name='sun', email='sun@163.com', password='235523')
db.session.add_all([ua, ub, uc, ud, ue, uf, ug, uh, ui, uj,uj,uj,uj,uj,uj,uj,uj,uj])
db.session.commit()
except Exception as e:
# 插入失敗自動(dòng)回滾
db.session.rollback()
raise e
app.run(debug=True)到此這篇關(guān)于Flask Paginate實(shí)現(xiàn)表格分頁(yè)的使用示例的文章就介紹到這了,更多相關(guān)Flask Paginate表格分頁(yè)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
python3中的eval和exec的區(qū)別與聯(lián)系
這篇文章主要介紹了python3中的eval和exec的區(qū)別與聯(lián)系,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-10-10
Python 中將二進(jìn)制轉(zhuǎn)換為整數(shù)的多種方法
這篇文章主要介紹了Python 中將二進(jìn)制轉(zhuǎn)換為整數(shù),Python 中提供了多種方式將二進(jìn)制字符串轉(zhuǎn)換為整數(shù),其中包括使用 int() 函數(shù)、使用二進(jìn)制前綴和使用 eval() 函數(shù),本文通過(guò)實(shí)例代碼講解的非常詳細(xì),需要的朋友可以參考下2023-05-05
Python利用xlrd和xlwt模塊進(jìn)行自動(dòng)化操作讀寫(xiě)Excel的完整指南
在日常工作中,Excel表格是不可或缺的數(shù)據(jù)處理工具,本文將介紹xlrd和xlwt模塊的參數(shù)說(shuō)明,并通過(guò)代碼實(shí)戰(zhàn)演示如何進(jìn)行Excel的讀寫(xiě)操作,有需要的可以了解下2025-11-11
詳細(xì)整理python 字符串(str)與列表(list)以及數(shù)組(array)之間的轉(zhuǎn)換方法
這篇文章主要介紹了詳細(xì)整理python 字符串(str)與列表(list)以及數(shù)組(array)之間的轉(zhuǎn)換方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Python常見(jiàn)報(bào)錯(cuò)解決之SciPy和NumPy版本沖突
Scipy是基于Numpy的科學(xué)計(jì)算工具庫(kù),方便、易于使用、專(zhuān)為科學(xué)和工程設(shè)計(jì),是一個(gè)用于數(shù)學(xué)、科學(xué)、工程領(lǐng)域的常用軟件包,這篇文章主要給大家介紹了關(guān)于Python常見(jiàn)報(bào)錯(cuò)解決之SciPy和NumPy版本沖突的相關(guān)資料,需要的朋友可以參考下2024-03-03
Python 經(jīng)典算法100及解析(小結(jié))
這篇文章主要介紹了Python 經(jīng)典算法100及解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
pytorch教程實(shí)現(xiàn)mnist手寫(xiě)數(shù)字識(shí)別代碼示例
這篇文章主要講解了pytorch教程中如何實(shí)現(xiàn)mnist手寫(xiě)數(shù)字識(shí)別,文中附有詳細(xì)的代碼示例,test準(zhǔn)確率98%,有需要的朋友可以借鑒參考下2021-09-09

