You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python框架结合Jinja实现网站分页?附JS+HTML方案

完全可以用Python结合Flask和Jinja实现分页,下面分两种方案说明,优先推荐后端分页(性能更优):

一、Python + Flask + Jinja 后端分页方案

后端分页不会一次性加载所有数据,适合数据量大的场景,核心是用SQLAlchemy的paginate方法实现数据库层面的分页查询。

1. 修改后端路由代码

接收前端传入的页码参数,替换全量查询为分页查询:

from flask import request

@blueprint.route('/community')
def community_page():
    # 获取当前页码,默认显示第1页
    page = request.args.get('page', 1, type=int)
    # 分页查询:每页10条,按发布时间倒序
    pagination = Discussions.query.filter(Discussions.title.isnot(None))\
        .order_by(Discussions.date.desc())\
        .paginate(page=page, per_page=10, error_out=False)
    
    discussions_json = []
    for discussion in pagination.items:
        # 优化提示:可通过join关联User表,避免循环中重复查询数据库
        user = User.query.filter_by(id=discussion.autor).first()
        discussions_json.append(
            {
                "id": discussion.id,
                "title": discussion.title,
                "text": discussion.text,
                "date": discussion.date,
                "username": user.username if user else "匿名",
                "answer_count": discussion.answer_count()
            }
        )
    
    # 将分页对象和数据传给模板
    return render_template("community.html", discussions_json=discussions_json, pagination=pagination)

2. 修改Jinja模板,添加分页导航

保留原讨论列表循环,在列表下方添加分页控制按钮:

<!-- 原讨论列表渲染逻辑 -->
{% for discussion in discussions_json %}
<a style="font-size: 19px; margin-right: auto; width: 88%; color:white; text-decoration:none; " href="/community/discussion/{{ discussion.id }}">{{ discussion.title }}</a> <span style="font-size: 25px; float: right; color: #0abab5;">{{ discussion.date.strftime("%H:%M | %d.%m.%Y") }}</span>
  <p style="font-size: 19px; margin-right: auto; width: 88%; color: red;">@{{ discussion.username }}</p>
  <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-chat-dots-fill" viewBox="0 0 16 16">
    <path d="M16 8c0 3.866-3.582 7-8 7a9 9 0 0 1-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7M5 8a1 1 0 1 0-2 0 1 1 0 0 0 2 0m4 0a1 1 0 1 0-2 0 1 1 0 0 0 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2"/>
  </svg>
  <span> {{ discussion.answer_count }}</span>
  <hr />
{% endfor %}

<!-- 分页导航控件 -->
<div style="margin-top: 20px; text-align: center;">
  <!-- 上一页按钮 -->
  {% if pagination.has_prev %}
    <a href="{{ url_for('blueprint.community_page', page=pagination.prev_num) }}" style="margin: 0 5px; padding: 8px 12px; background: #0abab5; color: white; text-decoration: none;">上一页</a>
  {% else %}
    <span style="margin: 0 5px; padding: 8px 12px; background: #ccc; color: #666;">上一页</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 %}
        <span style="margin: 0 5px; padding: 8px 12px; background: #0abab5; color: white; font-weight: bold;">{{ page_num }}</span>
      {% else %}
        <a href="{{ url_for('blueprint.community_page', page=page_num) }}" style="margin: 0 5px; padding: 8px 12px; background: #eee; color: #333; text-decoration: none;">{{ page_num }}</a>
      {% endif %}
    {% else %}
      <span style="margin: 0 5px;">...</span>
    {% endif %}
  {% endfor %}

  <!-- 下一页按钮 -->
  {% if pagination.has_next %}
    <a href="{{ url_for('blueprint.community_page', page=pagination.next_num) }}" style="margin: 0 5px; padding: 8px 12px; background: #0abab5; color: white; text-decoration: none;">下一页</a>
  {% else %}
    <span style="margin: 0 5px; padding: 8px 12px; background: #ccc; color: #666;">下一页</span>
  {% endif %}
</div>

pagination.iter_pages会自动生成合理的页码范围,避免页码过多导致的排版问题,参数可根据需求调整。

二、JS + HTML 前端分页方案(适合小数据量)

如果数据量较小,可一次性加载所有数据到前端,通过JS控制DOM元素的显示/隐藏实现分页,底层逻辑是计算当前页的条目索引范围:

1. 修改HTML结构

给每条讨论添加统一类名,新增分页控制区:

<!-- 讨论列表容器 -->
<div id="discussions-container">
  {% for discussion in discussions_json %}
  <div class="discussion-item">
    <a style="font-size: 19px; margin-right: auto; width: 88%; color:white; text-decoration:none; " href="/community/discussion/{{ discussion.id }}">{{ discussion.title }}</a> <span style="font-size: 25px; float: right; color: #0abab5;">{{ discussion.date.strftime("%H:%M | %d.%m.%Y") }}</span>
    <p style="font-size: 19px; margin-right: auto; width: 88%; color: red;">@{{ discussion.username }}</p>
    <svg xmlns="http://www.w3.org/2000/svg" width="32" height="32" fill="currentColor" class="bi bi-chat-dots-fill" viewBox="0 0 16 16">
      <path d="M16 8c0 3.866-3.582 7-8 7a9 9 0 0 1-2.347-.306c-.584.296-1.925.864-4.181 1.234-.2.032-.352-.176-.273-.362.354-.836.674-1.95.77-2.966C.744 11.37 0 9.76 0 8c0-3.866 3.582-7 8-7s8 3.134 8 7M5 8a1 1 0 1 0-2 0 1 1 0 0 0 2 0m4 0a1 1 0 1 0-2 0 1 1 0 0 0 2 0m3 1a1 1 0 1 0 0-2 1 1 0 0 0 0 2"/>
    </svg>
    <span> {{ discussion.answer_count }}</span>
    <hr />
  </div>
  {% endfor %}
</div>

<!-- 分页控制区 -->
<div id="pagination-controls" style="margin-top: 20px; text-align: center;">
  <button id="prev-btn" style="margin: 0 5px; padding: 8px 12px;">上一页</button>
  <span id="page-info"></span>
  <button id="next-btn" style="margin: 0 5px; padding: 8px 12px;">下一页</button>
</div>

2. 添加JS分页逻辑

在页面底部插入JS代码:

document.addEventListener('DOMContentLoaded', function() {
  const itemsPerPage = 10; // 每页显示10条
  const items = document.querySelectorAll('.discussion-item');
  const totalItems = items.length;
  const totalPages = Math.ceil(totalItems / itemsPerPage);
  let currentPage = 1;

  // 渲染指定页码的内容
  function showPage(page) {
    const startIndex = (page - 1) * itemsPerPage;
    const endIndex = startIndex + itemsPerPage;

    // 控制每条讨论的显示状态
    items.forEach((item, index) => {
      item.style.display = index >= startIndex && index < endIndex ? 'block' : 'none';
    });

    // 更新页码信息
    document.getElementById('page-info').textContent = `第 ${page} 页 / 共 ${totalPages} 页`;

    // 禁用/启用分页按钮
    document.getElementById('prev-btn').disabled = page === 1;
    document.getElementById('next-btn').disabled = page === totalPages;
  }

  // 上一页点击事件
  document.getElementById('prev-btn').addEventListener('click', () => {
    if (currentPage > 1) showPage(--currentPage);
  });

  // 下一页点击事件
  document.getElementById('next-btn').addEventListener('click', () => {
    if (currentPage < totalPages) showPage(++currentPage);
  });

  // 初始化显示第一页
  showPage(currentPage);
});

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 08:00:55