Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions flask_sqlalchemy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -325,7 +325,7 @@ def __init__(self, query, page, per_page, total, items):
@property
def pages(self):
"""The total number of pages"""
if self.per_page == 0:
if self.per_page == 0 or self.total is None:
pages = 0
else:
pages = int(ceil(self.total / float(self.per_page)))
Expand Down Expand Up @@ -427,13 +427,14 @@ def first_or_404(self):
abort(404)
return rv

def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None):
def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None, count=True):
"""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.
query, they default to 1 and 20 respectively. If ``count`` is ``False``,
no query to help determine total page count will be run.

When ``error_out`` is ``True`` (default), the following rules will
cause a 404 response:
Expand Down Expand Up @@ -494,8 +495,11 @@ def paginate(self, page=None, per_page=None, error_out=True, max_per_page=None):
abort(404)

# No need to count if we're on the first page and there are fewer
# items than we expected.
if page == 1 and len(items) < per_page:
# items than we expected or if count is disabled.

if not count:
total = None
elif page == 1 and len(items) < per_page:
total = len(items)
else:
total = self.order_by(None).count()
Expand Down
13 changes: 13 additions & 0 deletions tests/test_pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ def test_pagination_pages_when_0_items_per_page():
assert p.pages == 0


def test_pagination_pages_when_total_is_none():
p = fsa.Pagination(None, 1, 100, None, [])
assert p.pages == 0


def test_query_paginate(app, db, Todo):
with app.app_context():
db.session.add_all([Todo('', '') for _ in range(100)])
Expand Down Expand Up @@ -68,3 +73,11 @@ def test_paginate_min(app, db, Todo):

with pytest.raises(NotFound):
Todo.query.paginate(per_page=-1)


def test_paginate_without_count(app, db, Todo):
with app.app_context():
db.session.add_all(Todo('', '') for _ in range(20))
db.session.commit()

assert len(Todo.query.paginate(count=False, page=1, per_page=10).items) == 10