Allow passing -1 as the page number (returning the last page)

This commit is contained in:
Itai Shirav 2017-01-25 15:10:14 +02:00
parent 9f2619a807
commit ce8c77684e
3 changed files with 22 additions and 1 deletions

View File

@ -165,7 +165,7 @@ The ``paginate`` method returns a ``namedtuple`` containing the following fields
- ``objects`` - the list of objects in this page - ``objects`` - the list of objects in this page
- ``number_of_objects`` - total number of objects in all pages - ``number_of_objects`` - total number of objects in all pages
- ``pages_total`` - total number of pages - ``pages_total`` - total number of pages
- ``number`` - the page number - ``number`` - the page number, starting from 1; the special value -1 may be used to retrieve the last page
- ``page_size`` - the number of objects per page - ``page_size`` - the number of objects per page
You can optionally pass conditions to the query:: You can optionally pass conditions to the query::

View File

@ -87,6 +87,10 @@ class Database(object):
def paginate(self, model_class, order_by, page_num=1, page_size=100, conditions=None, settings=None): def paginate(self, model_class, order_by, page_num=1, page_size=100, conditions=None, settings=None):
count = self.count(model_class, conditions) count = self.count(model_class, conditions)
pages_total = int(ceil(count / float(page_size))) pages_total = int(ceil(count / float(page_size)))
if page_num == -1:
page_num = pages_total
elif page_num < 1:
raise ValueError('Invalid page number: %d' % page_num)
offset = (page_num - 1) * page_size offset = (page_num - 1) * page_size
query = 'SELECT * FROM $table' query = 'SELECT * FROM $table'
if conditions: if conditions:

View File

@ -93,6 +93,23 @@ class DatabaseTestCase(unittest.TestCase):
# Verify that all instances were returned # Verify that all instances were returned
self.assertEquals(len(instances), len(data)) self.assertEquals(len(instances), len(data))
def test_pagination_last_page(self):
self._insert_and_check(self._sample_data(), len(data))
# Try different page sizes
for page_size in (1, 2, 7, 10, 30, 100, 150):
# Ask for the last page in two different ways and verify equality
page_a = self.database.paginate(Person, 'first_name, last_name', -1, page_size)
page_b = self.database.paginate(Person, 'first_name, last_name', page_a.pages_total, page_size)
self.assertEquals(page_a[1:], page_b[1:])
self.assertEquals([obj.to_tsv() for obj in page_a.objects],
[obj.to_tsv() for obj in page_b.objects])
def test_pagination_invalid_page(self):
self._insert_and_check(self._sample_data(), len(data))
for page_num in (0, -2, -100):
with self.assertRaises(ValueError):
self.database.paginate(Person, 'first_name, last_name', page_num, 100)
def test_special_chars(self): def test_special_chars(self):
s = u'אבגד \\\'"`,.;éåäöšž\n\t\0\b\r' s = u'אבגד \\\'"`,.;éåäöšž\n\t\0\b\r'
p = Person(first_name=s) p = Person(first_name=s)