分页查询结果

如果你有很多结果,你可能只想一次显示一定数量的结果,允许用户点击下一页和上一页链接来查看数据页面。这有时称为分页,并使用动词分页

在选择语句上调用 SQLAlchemy.paginate() 以获取 Pagination 对象。

在请求期间,这将从查询字符串 request.args 中获取 pageper_page 参数。传递 max_per_page 以防止用户在单个页面上请求过多结果。如果没有给出,默认值为第 1 页,每页 20 项。

page = db.paginate(db.select(User).order_by(User.join_date))
return render_template("user/list.html", page=page)

显示项目

Pagination 对象的 Pagination.items 属性是当前页面的项目列表。该对象也可以直接迭代。

<ul>
  {% for user in page %}
    <li>{{ user.username }}
  {% endfor %}
</ul>

页面选择小部件

Pagination 对象具有可用于通过迭代页码和检查当前页来创建页面选择小部件的属性。 iter_pages() 将产生最多三组数字,用 None 分隔。它默认为在任一边缘显示 2 个页码,当前页之前 2 个数字,当前页,以及当前页之后的 4 个数字。例如,如果有 20 页且当前页为 7,则会产生以下值。

users.iter_pages()
[1, 2, None, 5, 6, 7, 8, 9, 10, 11, None, 19, 20]

你可以使用 total 属性来显示结果总数,以及 firstlast 来显示当前页上的项目范围。

以下 Jinja 宏呈现了一个简单的分页小部件。

{% macro render_pagination(pagination, endpoint) %}
  <div class="page-items">
    {{ pagination.first }} - {{ pagination.last }} of {{ pagination.total }}
  </div>
  <div class=pagination>
    {% for page in pagination.iter_pages() %}
      {% if page %}
        {% if page != pagination.page %}
          <a href="{{ url_for(endpoint, page=page) }}">{{ page }}</a>
        {% else %}
          <strong>{{ page }}</strong>
        {% endif %}
      {% else %}
        <span class=ellipsis>…</span>
      {% endif %}
    {% endfor %}
  </div>
{% endmacro %}