Flask实现分页的三种方法
在 Flask
中实现分页的方式有多种,最常用的是使用 Flask-SQLAlchemy
自带的分页功能,或者手动实现分页逻辑。下面介绍几种方法:
方法 1:使用 Flask-SQLAlchemy 的 paginate()
Flask-SQLAlchemy
提供了 paginate()
方法,可以轻松实现分页。
1. 安装 Flask-SQLAlchemy
pip install flask flask-sqlalchemy
2. 代码示例
from flask import Flask, request, render_template
from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///database.db'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class Item(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100), nullable=False)
# 创建数据库并填充数据
with app.app_context():
db.create_all()
if not Item.query.first(): # 如果表为空,添加测试数据
for i in range(1, 101):
db.session.add(Item(name=f"Item {i}"))
db.session.commit()
@app.route('/items')
def items():
page = request.args.get('page', 1, type=int) # 获取当前页码,默认为第1页
per_page = 10 # 每页显示10条数据
pagination = Item.query.paginate(page=page, per_page=per_page, error_out=False)
return render_template('items.html', pagination=pagination)
if __name__ == '__main__':
app.run(debug=True)
3. 创建 HTML 模板(templates/items.html
)
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>分页示例</title>
</head>
<body>
<h1>分页示例</h1>
<ul>
{% for item in pagination.items %}
<li>{{ item.name }}</li>
{% endfor %}
</ul>
<div>
{% if pagination.has_prev %}
<a href="{{ url_for('items', page=pagination.prev_num) }}">上一页</a>
{% endif %}
<span>第 {{ pagination.page }} 页 / 共 {{ pagination.pages }} 页</span>
{% if pagination.has_next %}
<a href="{{ url_for('items', page=pagination.next_num) }}">下一页</a>
{% endif %}
</div>
</body>
</html>
方法 2:使用手动分页
如果你不使用 Flask-SQLAlchemy
,可以手动实现分页逻辑。例如:
from flask import Flask, request, render_template
app = Flask(__name__)
# 假设这是数据库中的数据
data = [f"Item {i}" for i in range(1, 101)] # 100 个数据
@app.route('/items')
def items():
page = request.args.get('page', 1, type=int)
per_page = 10
start = (page - 1) * per_page
end = start + per_page
total_pages = (len(data) + per_page - 1) // per_page # 计算总页数
return render_template('items.html', items=data[start:end], page=page, total_pages=total_pages)
if __name__ == '__main__':
app.run(debug=True)
对应 HTML
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>手动分页</title>
</head>
<body>
<h1>手动分页示例</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div>
{% if page > 1 %}
<a href="{{ url_for('items', page=page-1) }}">上一页</a>
{% endif %}
<span>第 {{ page }} 页 / 共 {{ total_pages }} 页</span>
{% if page < total_pages %}
<a href="{{ url_for('items', page=page+1) }}">下一页</a>
{% endif %}
</div>
</body>
</html>
方法 3:使用 Flask-Paginate
Flask-Paginate
是一个用于分页的扩展,适用于数据库查询或普通列表分页。
1. 安装 Flask-Paginate
pip install Flask-Paginate
2. 代码示例
from flask import Flask, request, render_template
from flask_paginate import Pagination, get_page_args
app = Flask(__name__)
# 假设数据存储在列表中
data = [f"Item {i}" for i in range(1, 101)] # 100 条数据
def get_items(offset=0, per_page=10):
return data[offset: offset + per_page]
@app.route('/items')
def items():
page, per_page, offset = get_page_args(page_parameter='page', per_page_parameter='per_page', default=10)
total = len(data)
items = get_items(offset=offset, per_page=per_page)
pagination = Pagination(page=page, per_page=per_page, total=total, css_framework='bootstrap4')
return render_template('items.html', items=items, pagination=pagination)
if __name__ == '__main__':
app.run(debug=True)
对应 HTML
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<title>Flask-Paginate 分页</title>
</head>
<body>
<h1>Flask-Paginate 分页示例</h1>
<ul>
{% for item in items %}
<li>{{ item }}</li>
{% endfor %}
</ul>
<div>
{{ pagination.links }}
</div>
</body>
</html>
总结
方法 | 适用场景 | 复杂度 | 适用数据库 |
---|---|---|---|
Flask-SQLAlchemy paginate() | SQLAlchemy 数据库 | ⭐ | 适用于数据库 |
手动分页 | 适用于列表/非数据库数据 | ⭐⭐ | 适用于普通列表 |
Flask-Paginate | 需要更好 UI 和分页控制 | ⭐⭐⭐ | 适用于数据库和列表 |
如果你正在使用 SQLAlchemy
,推荐使用 paginate()
方法;如果你是基于列表或 API 数据分页,Flask-Paginate
可能是更好的选择。 🚀