You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Flask中如何实现动态列表的多页面分页展示?

Flask 动态列表分页最优实现方案

嘿,这个需求其实很常见,我推荐优先用Flask-SQLAlchemy 内置的分页功能(如果你的数据存在数据库里),这是最简洁高效的方案;如果数据来自非数据库的普通列表,也可以手动实现分页逻辑,下面两种场景我都给你讲清楚:


场景1:数据来自SQLAlchemy模型(推荐)

假设你的数据存在Item模型中,直接用paginate()方法就能搞定分页,它会在数据库层面做LIMITOFFSET查询,不会一次性加载所有数据,性能更优:

1. 修改app.py中的路由

from flask import Flask, render_template
from your_models import Item  # 导入你的数据模型
from flask_sqlalchemy import SQLAlchemy

app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = '你的数据库连接字符串'
db = SQLAlchemy(app)

@app.route('/displayitems')
@app.route('/displayitems/page/<int:page>')
def display_items(page=1):
    # per_page设为20,page默认值1(即默认显示第一页)
    # error_out=False避免用户访问超页数时返回404,改为返回空列表
    pagination = Item.query.paginate(page=page, per_page=20, error_out=False)
    current_items = pagination.items  # 当前页的20条数据
    return render_template('displayitems.html', pagination=pagination, items=current_items)

2. 修改displayitems.html模板

在模板里展示数据+分页控制按钮,还能智能生成页码导航:

<!-- 展示当前页数据 -->
<ul>
    {% for item in items %}
        <li>{{ item.title }}</li>  <!-- 替换成你的数据字段,比如item.id、item.content等 -->
    {% endfor %}
</ul>

<!-- 分页控制区 -->
<div class="pagination">
    <!-- 上一页按钮 -->
    {% if pagination.has_prev %}
        <a href="{{ url_for('display_items', page=pagination.prev_num) }}">上一页</a>
    {% else %}
        <span style="color:#ccc">上一页</span>  <!-- 无数据时置灰不可点击 -->
    {% endif %}

    <!-- 智能页码导航(避免显示过多页码) -->
    {% for page_num in pagination.iter_pages(left_edge=1, right_edge=1, left_current=2, right_current=3) %}
        {% if page_num %}
            {% if page_num == pagination.page %}
                <strong>{{ page_num }}</strong>  <!-- 当前页码高亮显示 -->
            {% else %}
                <a href="{{ url_for('display_items', page=page_num) }}">{{ page_num }}</a>
            {% endif %}
        {% else %}
            <span>...</span>
        {% endif %}
    {% endfor %}

    <!-- 下一页按钮 -->
    {% if pagination.has_next %}
        <a href="{{ url_for('display_items', page=pagination.next_num) }}">下一页</a>
    {% else %}
        <span style="color:#ccc">下一页</span>
    {% endif %}
</div>

iter_pages()的参数可以按需调整,比如left_edge=1表示最左侧显示1个页码,left_current=2表示当前页码左侧显示2个页码,能让分页导航更简洁。


场景2:数据是普通Python列表(非数据库)

如果你的数据来自API、本地文件等非数据库来源,手动计算分页逻辑也很简单:

1. 修改app.py中的路由

from flask import Flask, render_template

app = Flask(__name__)

# 模拟你的动态列表数据(实际中替换成你的数据获取逻辑)
def get_all_items():
    return [f"商品{i}" for i in range(1000)]

@app.route('/displayitems')
@app.route('/displayitems/page/<int:page>')
def display_items(page=1):
    per_page = 20
    all_items = get_all_items()
    total_count = len(all_items)
    
    # 计算当前页数据的起始/结束索引
    start_idx = (page - 1) * per_page
    end_idx = start_idx + per_page
    current_items = all_items[start_idx:end_idx]
    
    # 分页状态计算
    has_prev = page > 1
    has_next = end_idx < total_count
    prev_page = page - 1 if has_prev else None
    next_page = page + 1 if has_next else None
    total_pages = (total_count + per_page - 1) // per_page  # 向上取整算总页数

    return render_template('displayitems.html', 
                          items=current_items,
                          has_prev=has_prev,
                          has_next=has_next,
                          prev_page=prev_page,
                          next_page=next_page,
                          current_page=page,
                          total_pages=total_pages)

2. 修改displayitems.html模板

<ul>
    {% for item in items %}
        <li>{{ item }}</li>
    {% endfor %}
</ul>

<div class="pagination">
    {% if has_prev %}
        <a href="{{ url_for('display_items', page=prev_page) }}">上一页</a>
    {% else %}
        <span style="color:#ccc">上一页</span>
    {% endif %}

    <span>第 {{ current_page }} / {{ total_pages }} 页</span>

    {% if has_next %}
        <a href="{{ url_for('display_items', page=next_page) }}">下一页</a>
    {% else %}
        <span style="color:#ccc">下一页</span>
    {% endif %}
</div>

为什么这是最优方案?

  • SQLAlchemy分页:直接在数据库层面做分页,避免一次性加载上千条数据到内存,大幅提升性能和加载速度。
  • 手动分页:逻辑清晰易维护,适合非数据库场景,同样能避免内存过载。
  • 两种方案都采用URL传递页码参数,符合RESTful风格,用户可以直接收藏或分享某一页的链接,体验更友好。

内容的提问来源于stack exchange,提问作者LuckyB

火山引擎 最新活动