前言
Flask-SQLAlchemy 提供了一个分页查询方法 paginate(),方便我们实现在后端查询分页。
分页查询
在django 框架里面有个rest_framework.pagination 分页器, 只需简单的配置就可以实现分页
from rest_framework.pagination import PageNumberPagination
# 定义分页器简单分页(PageNumberPagination)
class MyPageNumberPagination(PageNumberPagination):
page_size = 50 # 默认每页显示的多少条记录
page_query_param = 'page' # 默认查询参数名为 page
page_size_query_param = 'size' # 前台控制每页显示的最大条数
max_page_size = 100 # 后台控制显示的最大记录条数
Flask-SQLAlchemy 也提供了一个 paginate()查询方法, 相关源码如下
def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None):
"""Returns ``per_page`` items from page ``page``.
If ``page`` or ``per_page`` are ``None``, they will be retrieved from
the request query. If ``max_per_page`` is specified, ``per_page`` will
be limited to that value. If there is no request or they aren't in the
query, they default to 1 and 20 respectively.
When ``error_out`` is ``True`` (default), the following rules will
cause a 404 response:
* No items are found and ``page`` is not 1.
* ``page`` is less than 1, or ``per_page`` is negative.
* ``page`` or ``per_page`` are not ints.
When ``error_out`` is ``False``, ``page`` and ``per_page`` default to
1 and 20 respectively.
Returns a :class:`Pagination` object.
"""
return Pagination(self, page, per_page, total, items)
参数说明:
page: 指定页码,从1开始
per_page: 每一页显示几条数据
error_out:是否抛出错误(默认为True)大部分error_out
是False
, page
and per_page
默认值是 1和20
max_per_page:每页显示最大值当指定了max_per_page时,per_page会受到这个值的限制
调用 paginate()查询方法会返回一个Pagination
对象的实例
class Pagination(object):
"""Internal helper class returned by :meth:`BaseQuery.paginate`. You
can also construct it from any other SQLAlchemy query object if you are
working with other libraries. Additionally it is possible to pass `None`
as query object in which case the :meth:`prev` and :meth:`next` will
no longer work.
"""
def __init__(self, query, page, per_page, total, items):
#: the unlimited query object that was used to create this
#: pagination object.
self.query = query
#: the current page number (1 indexed)
self.page = page
#: the number of items to be displayed on a page.
self.per_page = per_page
#: the total number of items matching the query
self.total = total
#: the items for the current page
self.items = items
Pagination类对象的属性主要有:
has_next:如果在目前页后至少还有一页的话,返回 True。
has_prev:如果在目前页之前至少还有一页的话,返回 True。
next_num:下一页的页面数。
prev_num:前一页的页面数。
另外还有如下的可调用方法:
iter_pages():一个迭代器,返回一个在分页导航中显示的页数列表。
prev():上一页的分页对象。
next():下一页的分页对象。
实例属性有
query:创建Pagination对象对应的query对象
total:匹配的元素总数
per_page:每一页显示的元素个数
items:当前页面的查询结果
分页查询接口
from flask import make_response, request
from http import HTTPStatus
@api.route('/demo')
class ProjectInfoView(Resource):
@api.doc(description='查询')
@api.marshal_with(project_model)
def get(self):
"""查询全部"""
api.logger.info(f"GET query查询参数: {request.args}")
# 按id倒序
objs = Demo.query.order_by(Demo.id.desc())
# 分页 page=None, per_page=None, error_out=True, max_per_page=None
page_objs = objs.paginate(
page=int(request.args.get("page")),
per_page=int(request.args.get("size")),
error_out=False,
max_per_page=50
).items
return page_objs, HTTPStatus.OK
分页接口查询示例/demo?page=1&size=3