allow ordering to be cleared

This commit is contained in:
Stefan Wojcik 2014-03-07 16:08:06 -08:00 committed by Ross Lawley
parent 0971ad0a80
commit 5e776a07dd
2 changed files with 42 additions and 58 deletions

View File

@ -192,7 +192,7 @@ class BaseQuerySet(object):
.. versionadded:: 0.3 .. versionadded:: 0.3
""" """
queryset = self.clone() queryset = self.clone()
queryset = queryset.limit(2) queryset = queryset.order_by().limit(2)
queryset = queryset.filter(*q_objs, **query) queryset = queryset.filter(*q_objs, **query)
try: try:

View File

@ -14,8 +14,8 @@ from pymongo.read_preferences import ReadPreference
from bson import ObjectId from bson import ObjectId
from mongoengine import * from mongoengine import *
from mongoengine.connection import get_connection
from mongoengine.python_support import PY3 from mongoengine.python_support import PY3
from mongoengine.connection import get_connection
from mongoengine.context_managers import query_counter, switch_db from mongoengine.context_managers import query_counter, switch_db
from mongoengine.queryset import (QuerySet, QuerySetManager, from mongoengine.queryset import (QuerySet, QuerySetManager,
MultipleObjectsReturned, DoesNotExist, MultipleObjectsReturned, DoesNotExist,
@ -25,6 +25,12 @@ from mongoengine.errors import InvalidQueryError
__all__ = ("QuerySetTest",) __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): class QuerySetTest(unittest.TestCase):
def setUp(self): def setUp(self):
@ -1048,74 +1054,52 @@ class QuerySetTest(unittest.TestCase):
self.assertSequence(qs, expected) self.assertSequence(qs, expected)
def test_clear_ordering(self): def test_clear_ordering(self):
""" Make sure one can clear the query set ordering by applying a """ Ensure that the default ordering can be cleared by calling order_by().
consecutive 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 = { meta = {
'ordering': ['-name'] 'ordering': ['-published_date']
} }
Person.drop_collection() BlogPost.drop_collection()
Person(name="A").save()
Person(name="B").save()
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 db_ops_tracker() as q:
with query_counter() as q: BlogPost.objects.filter(title='whatever').order_by().first()
lst = list(qs.order_by()) 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": def test_no_ordering_for_get(self):
{"$ne": "%s.system.indexes" % q.db.name}})[0] """ 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']) meta = {
self.assertEqual(lst[0].name, 'A') 'ordering': ['-published_date']
}
# Make sure default ordering is preserved during consecutive calls BlogPost.objects.create(title='whatever', published_date=datetime.utcnow())
# to the same query set
with query_counter() as q:
lst = list(qs)
op = q.db.system.profile.find({"ns": with db_ops_tracker() as q:
{"$ne": "%s.system.indexes" % q.db.name}})[0] 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']) # Ordering should be ignored for .get even if we set it explicitly
self.assertEqual(lst[0].name, 'B') 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): def test_find_embedded(self):
"""Ensure that an embedded document is properly returned from a query. """Ensure that an embedded document is properly returned from a query.