From 5e776a07dd2a267017a3d91723ea7dbf1ab826a4 Mon Sep 17 00:00:00 2001 From: Stefan Wojcik Date: Fri, 7 Mar 2014 16:08:06 -0800 Subject: [PATCH] allow ordering to be cleared --- mongoengine/queryset/base.py | 2 +- tests/queryset/queryset.py | 98 +++++++++++++++--------------------- 2 files changed, 42 insertions(+), 58 deletions(-) diff --git a/mongoengine/queryset/base.py b/mongoengine/queryset/base.py index 4c37d989..be5d66b0 100644 --- a/mongoengine/queryset/base.py +++ b/mongoengine/queryset/base.py @@ -192,7 +192,7 @@ class BaseQuerySet(object): .. versionadded:: 0.3 """ queryset = self.clone() - queryset = queryset.limit(2) + queryset = queryset.order_by().limit(2) queryset = queryset.filter(*q_objs, **query) try: diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index 5b18dc63..4770c3e6 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -14,8 +14,8 @@ from pymongo.read_preferences import ReadPreference from bson import ObjectId from mongoengine import * -from mongoengine.connection import get_connection from mongoengine.python_support import PY3 +from mongoengine.connection import get_connection from mongoengine.context_managers import query_counter, switch_db from mongoengine.queryset import (QuerySet, QuerySetManager, MultipleObjectsReturned, DoesNotExist, @@ -25,6 +25,12 @@ from mongoengine.errors import InvalidQueryError __all__ = ("QuerySetTest",) +class db_ops_tracker(query_counter): + def get_ops(self): + ignore_query = {"ns": {"$ne": "%s.system.indexes" % self.db.name}} + return list(self.db.system.profile.find(ignore_query)) + + class QuerySetTest(unittest.TestCase): def setUp(self): @@ -1048,74 +1054,52 @@ class QuerySetTest(unittest.TestCase): self.assertSequence(qs, expected) def test_clear_ordering(self): - """ Make sure one can clear the query set ordering by applying a - consecutive order_by() + """ Ensure that the default ordering can be cleared by calling order_by(). """ + class BlogPost(Document): + title = StringField() + published_date = DateTimeField() - class Person(Document): - name = StringField() - - Person.drop_collection() - Person(name="A").save() - Person(name="B").save() - - qs = Person.objects.order_by('-name') - - # Make sure we can clear a previously specified ordering - with query_counter() as q: - lst = list(qs.order_by()) - - op = q.db.system.profile.find({"ns": - {"$ne": "%s.system.indexes" % q.db.name}})[0] - - self.assertTrue('$orderby' not in op['query']) - self.assertEqual(lst[0].name, 'A') - - # Make sure previously specified ordering is preserved during - # consecutive calls to the same query set - with query_counter() as q: - lst = list(qs) - - op = q.db.system.profile.find({"ns": - {"$ne": "%s.system.indexes" % q.db.name}})[0] - - self.assertTrue('$orderby' in op['query']) - self.assertEqual(lst[0].name, 'B') - - def test_clear_default_ordering(self): - - class Person(Document): - name = StringField() meta = { - 'ordering': ['-name'] + 'ordering': ['-published_date'] } - Person.drop_collection() - Person(name="A").save() - Person(name="B").save() + BlogPost.drop_collection() - qs = Person.objects + with db_ops_tracker() as q: + BlogPost.objects.filter(title='whatever').first() + self.assertEqual(len(q.get_ops()), 1) + self.assertEqual(q.get_ops()[0]['query']['$orderby'], {u'published_date': -1}) - # Make sure clearing default ordering works - with query_counter() as q: - lst = list(qs.order_by()) + with db_ops_tracker() as q: + BlogPost.objects.filter(title='whatever').order_by().first() + self.assertEqual(len(q.get_ops()), 1) + print q.get_ops()[0]['query'] + self.assertFalse('$orderby' in q.get_ops()[0]['query']) - op = q.db.system.profile.find({"ns": - {"$ne": "%s.system.indexes" % q.db.name}})[0] + def test_no_ordering_for_get(self): + """ Ensure that Doc.objects.get doesn't use any ordering. + """ + class BlogPost(Document): + title = StringField() + published_date = DateTimeField() - self.assertTrue('$orderby' not in op['query']) - self.assertEqual(lst[0].name, 'A') + meta = { + 'ordering': ['-published_date'] + } - # Make sure default ordering is preserved during consecutive calls - # to the same query set - with query_counter() as q: - lst = list(qs) + BlogPost.objects.create(title='whatever', published_date=datetime.utcnow()) - op = q.db.system.profile.find({"ns": - {"$ne": "%s.system.indexes" % q.db.name}})[0] + with db_ops_tracker() as q: + BlogPost.objects.get(title='whatever') + self.assertEqual(len(q.get_ops()), 1) + self.assertFalse('$orderby' in q.get_ops()[0]['query']) - self.assertTrue('$orderby' in op['query']) - self.assertEqual(lst[0].name, 'B') + # Ordering should be ignored for .get even if we set it explicitly + with db_ops_tracker() as q: + BlogPost.objects.order_by('-title').get(title='whatever') + self.assertEqual(len(q.get_ops()), 1) + self.assertFalse('$orderby' in q.get_ops()[0]['query']) def test_find_embedded(self): """Ensure that an embedded document is properly returned from a query.