From 1afe7240f4982a0d714cf69a2ee34ca2998bf0e3 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Mon, 16 Jan 2012 09:03:12 +0000 Subject: [PATCH] Fixed pagination limit / skip bug fixes #398 --- docs/changelog.rst | 1 + mongoengine/queryset.py | 24 ++++++++++++------------ tests/django_tests.py | 21 +++++++++++++++++++++ 3 files changed, 34 insertions(+), 12 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index ab4d9492..0215335f 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,7 @@ Changelog Changes in dev ============== +- Fixed limit skip bug - Added values_list for returning a list of data - Improved Inheritance / Mixin - Added sharding support diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 84b3d90e..34c920ef 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -327,10 +327,10 @@ class ListResult(object): self.GenericReferenceField = GenericReferenceField self._cursor = cursor - + f = [] for field, dbfield in itertools.izip(fields, dbfields): - + p = document_type for path in field.split('.'): if p and isinstance(p, BaseField): @@ -343,7 +343,7 @@ class ListResult(object): f.append((dbfield.split('.'), p)) self._fields = f - + def _get_value(self, keys, field_type, data): for key in keys: if data: @@ -354,17 +354,17 @@ class ListResult(object): if isinstance(field_type, self.ReferenceField): doc_type = field_type.document_type data = doc_type._get_db().dereference(data) - + if data: return doc_type._from_son(data) elif isinstance(field_type, self.GenericReferenceField): if data and isinstance(data, (dict, pymongo.dbref.DBRef)): return field_type.dereference(data) - + if data is None: return - + return field_type.to_python(data) def next(self): @@ -638,13 +638,13 @@ class QuerySet(object): self._ordering = self._get_order_key_list( *self._document._meta['ordering']) obj.sort(self._ordering) - + if self._limit is not None: - obj.limit(self._limit) - + obj.limit(self._limit - (self._skip or 0)) + if self._skip is not None: obj.skip(self._skip) - + if self._hint != -1: obj.hint(self._hint) @@ -654,7 +654,7 @@ class QuerySet(object): def _cursor(self): if self._cursor_obj is None: self._cursor_obj = self._build_cursor(**self._cursor_args) - + return self._cursor_obj @classmethod def _lookup_field(cls, document, parts): @@ -1286,7 +1286,7 @@ class QuerySet(object): :param keys: fields to order the query results by; keys may be prefixed with **+** or **-** to determine the ordering direction """ - + key_list = self._get_order_key_list(*keys) self._ordering = key_list self._cursor.sort(key_list) diff --git a/tests/django_tests.py b/tests/django_tests.py index 9c7e3280..3341eb1c 100644 --- a/tests/django_tests.py +++ b/tests/django_tests.py @@ -8,6 +8,8 @@ from mongoengine.django.shortcuts import get_document_or_404 from django.http import Http404 from django.template import Context, Template from django.conf import settings +from django.core.paginator import Paginator + settings.configure() class QuerySetTest(unittest.TestCase): @@ -67,3 +69,22 @@ class QuerySetTest(unittest.TestCase): self.assertRaises(Http404, get_document_or_404, self.Person, pk='1234') self.assertEqual(p, get_document_or_404(self.Person, pk=p.pk)) + def test_pagination(self): + """Ensure that Pagination works as expected + """ + class Page(Document): + name = StringField() + + Page.drop_collection() + + for i in xrange(1, 11): + Page(name=str(i)).save() + + paginator = Paginator(Page.objects.all(), 2) + + t = Template("{% for i in page.object_list %}{{ i.name }}:{% endfor %}") + for p in paginator.page_range: + d = {"page": paginator.page(p)} + end = p * 2 + start = end - 1 + self.assertEqual(t.render(Context(d)), u'%d:%d:' % (start, end))