Merge branch 'master' into limit_behaviour
This commit is contained in:
		| @@ -3,12 +3,14 @@ | ||||
| import datetime | ||||
| import unittest | ||||
| import uuid | ||||
| from decimal import Decimal | ||||
|  | ||||
| from bson import DBRef, ObjectId | ||||
| from nose.plugins.skip import SkipTest | ||||
| import pymongo | ||||
| from pymongo.errors import ConfigurationError | ||||
| from pymongo.read_preferences import ReadPreference | ||||
| from pymongo.results import UpdateResult | ||||
| import six | ||||
|  | ||||
| from mongoengine import * | ||||
| @@ -57,11 +59,10 @@ class QuerySetTest(unittest.TestCase): | ||||
|     def test_initialisation(self): | ||||
|         """Ensure that a QuerySet is correctly initialised by QuerySetManager. | ||||
|         """ | ||||
|         self.assertTrue(isinstance(self.Person.objects, QuerySet)) | ||||
|         self.assertIsInstance(self.Person.objects, QuerySet) | ||||
|         self.assertEqual(self.Person.objects._collection.name, | ||||
|                          self.Person._get_collection_name()) | ||||
|         self.assertTrue(isinstance(self.Person.objects._collection, | ||||
|                                    pymongo.collection.Collection)) | ||||
|         self.assertIsInstance(self.Person.objects._collection, pymongo.collection.Collection) | ||||
|  | ||||
|     def test_cannot_perform_joins_references(self): | ||||
|  | ||||
| @@ -87,8 +88,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|         self.assertEqual(people.count(), 2) | ||||
|         results = list(people) | ||||
|  | ||||
|         self.assertTrue(isinstance(results[0], self.Person)) | ||||
|         self.assertTrue(isinstance(results[0].id, (ObjectId, str, unicode))) | ||||
|         self.assertIsInstance(results[0], self.Person) | ||||
|         self.assertIsInstance(results[0].id, (ObjectId, str, unicode)) | ||||
|  | ||||
|         self.assertEqual(results[0], user_a) | ||||
|         self.assertEqual(results[0].name, 'User A') | ||||
| @@ -228,7 +229,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         # Retrieve the first person from the database | ||||
|         person = self.Person.objects.first() | ||||
|         self.assertTrue(isinstance(person, self.Person)) | ||||
|         self.assertIsInstance(person, self.Person) | ||||
|         self.assertEqual(person.name, "User A") | ||||
|         self.assertEqual(person.age, 20) | ||||
|  | ||||
| @@ -594,6 +595,20 @@ class QuerySetTest(unittest.TestCase): | ||||
|         Scores.objects(id=scores.id).update(max__high_score=500) | ||||
|         self.assertEqual(Scores.objects.get(id=scores.id).high_score, 1000) | ||||
|  | ||||
|     @needs_mongodb_v26 | ||||
|     def test_update_multiple(self): | ||||
|         class Product(Document): | ||||
|             item = StringField() | ||||
|             price = FloatField() | ||||
|  | ||||
|         product = Product.objects.create(item='ABC', price=10.99) | ||||
|         product = Product.objects.create(item='ABC', price=10.99) | ||||
|         Product.objects(id=product.id).update(mul__price=1.25) | ||||
|         self.assertEqual(Product.objects.get(id=product.id).price, 13.7375) | ||||
|         unknown_product = Product.objects.create(item='Unknown') | ||||
|         Product.objects(id=unknown_product.id).update(mul__price=100) | ||||
|         self.assertEqual(Product.objects.get(id=unknown_product.id).price, 0) | ||||
|  | ||||
|     def test_updates_can_have_match_operators(self): | ||||
|  | ||||
|         class Comment(EmbeddedDocument): | ||||
| @@ -661,14 +676,14 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         result = self.Person(name="Bob", age=25).update( | ||||
|             upsert=True, full_result=True) | ||||
|         self.assertTrue(isinstance(result, dict)) | ||||
|         self.assertTrue("upserted" in result) | ||||
|         self.assertFalse(result["updatedExisting"]) | ||||
|         self.assertIsInstance(result, UpdateResult) | ||||
|         self.assertIn("upserted", result.raw_result) | ||||
|         self.assertFalse(result.raw_result["updatedExisting"]) | ||||
|  | ||||
|         bob = self.Person.objects.first() | ||||
|         result = bob.update(set__age=30, full_result=True) | ||||
|         self.assertTrue(isinstance(result, dict)) | ||||
|         self.assertTrue(result["updatedExisting"]) | ||||
|         self.assertIsInstance(result, UpdateResult) | ||||
|         self.assertTrue(result.raw_result["updatedExisting"]) | ||||
|  | ||||
|         self.Person(name="Bob", age=20).save() | ||||
|         result = self.Person.objects(name="Bob").update( | ||||
| @@ -835,11 +850,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|                 blogs.append(Blog(title="post %s" % i, posts=[post1, post2])) | ||||
|  | ||||
|             Blog.objects.insert(blogs, load_bulk=False) | ||||
|             if mongodb_version < (2, 6): | ||||
|                 self.assertEqual(q, 1) | ||||
|             else: | ||||
|                 # profiling logs each doc now in the bulk op | ||||
|                 self.assertEqual(q, 99) | ||||
|             # profiling logs each doc now in the bulk op | ||||
|             self.assertEqual(q, 99) | ||||
|  | ||||
|         Blog.drop_collection() | ||||
|         Blog.ensure_indexes() | ||||
| @@ -848,11 +860,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             self.assertEqual(q, 0) | ||||
|  | ||||
|             Blog.objects.insert(blogs) | ||||
|             if mongodb_version < (2, 6): | ||||
|                 self.assertEqual(q, 2)  # 1 for insert, and 1 for in bulk fetch | ||||
|             else: | ||||
|                 # 99 for insert, and 1 for in bulk fetch | ||||
|                 self.assertEqual(q, 100) | ||||
|             self.assertEqual(q, 100) # 99 for insert 1 for fetch | ||||
|  | ||||
|         Blog.drop_collection() | ||||
|  | ||||
| @@ -917,10 +925,6 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         self.assertEqual(Blog.objects.count(), 2) | ||||
|  | ||||
|         Blog.objects.insert([blog2, blog3], | ||||
|                             write_concern={"w": 0, 'continue_on_error': True}) | ||||
|         self.assertEqual(Blog.objects.count(), 3) | ||||
|  | ||||
|     def test_get_changed_fields_query_count(self): | ||||
|         """Make sure we don't perform unnecessary db operations when | ||||
|         none of document's fields were updated. | ||||
| @@ -994,7 +998,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         # Retrieve the first person from the database | ||||
|         person = self.Person.objects.slave_okay(True).first() | ||||
|         self.assertTrue(isinstance(person, self.Person)) | ||||
|         self.assertIsInstance(person, self.Person) | ||||
|         self.assertEqual(person.name, "User A") | ||||
|         self.assertEqual(person.age, 20) | ||||
|  | ||||
| @@ -1061,10 +1065,10 @@ class QuerySetTest(unittest.TestCase): | ||||
|         self.assertEqual(docs.count(), 1000) | ||||
|  | ||||
|         docs_string = "%s" % docs | ||||
|         self.assertTrue("Doc: 0" in docs_string) | ||||
|         self.assertIn("Doc: 0", docs_string) | ||||
|  | ||||
|         self.assertEqual(docs.count(), 1000) | ||||
|         self.assertTrue('(remaining elements truncated)' in "%s" % docs) | ||||
|         self.assertIn('(remaining elements truncated)', "%s" % docs) | ||||
|  | ||||
|         # Limit and skip | ||||
|         docs = docs[1:4] | ||||
| @@ -1203,6 +1207,14 @@ class QuerySetTest(unittest.TestCase): | ||||
|         BlogPost.drop_collection() | ||||
|         Blog.drop_collection() | ||||
|  | ||||
|     def test_filter_chaining_with_regex(self): | ||||
|         person = self.Person(name='Guido van Rossum') | ||||
|         person.save() | ||||
|  | ||||
|         people = self.Person.objects | ||||
|         people = people.filter(name__startswith='Gui').filter(name__not__endswith='tum') | ||||
|         self.assertEqual(people.count(), 1) | ||||
|  | ||||
|     def assertSequence(self, qs, expected): | ||||
|         qs = list(qs) | ||||
|         expected = list(expected) | ||||
| @@ -1273,7 +1285,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|         with db_ops_tracker() as q: | ||||
|             BlogPost.objects.filter(title='whatever').order_by().first() | ||||
|             self.assertEqual(len(q.get_ops()), 1) | ||||
|             self.assertFalse('$orderby' in q.get_ops()[0]['query']) | ||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) | ||||
|  | ||||
|         # calling an explicit order_by should use a specified sort | ||||
|         with db_ops_tracker() as q: | ||||
| @@ -1289,7 +1301,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             qs = BlogPost.objects.filter(title='whatever').order_by('published_date') | ||||
|             qs.order_by().first() | ||||
|             self.assertEqual(len(q.get_ops()), 1) | ||||
|             self.assertFalse('$orderby' in q.get_ops()[0]['query']) | ||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) | ||||
|  | ||||
|     def test_no_ordering_for_get(self): | ||||
|         """ Ensure that Doc.objects.get doesn't use any ordering. | ||||
| @@ -1308,13 +1320,13 @@ class QuerySetTest(unittest.TestCase): | ||||
|         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.assertNotIn('$orderby', q.get_ops()[0]['query']) | ||||
|  | ||||
|         # 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']) | ||||
|             self.assertNotIn('$orderby', q.get_ops()[0]['query']) | ||||
|  | ||||
|     def test_find_embedded(self): | ||||
|         """Ensure that an embedded document is properly returned from | ||||
| @@ -1336,15 +1348,15 @@ class QuerySetTest(unittest.TestCase): | ||||
|         ) | ||||
|  | ||||
|         result = BlogPost.objects.first() | ||||
|         self.assertTrue(isinstance(result.author, User)) | ||||
|         self.assertIsInstance(result.author, User) | ||||
|         self.assertEqual(result.author.name, 'Test User') | ||||
|  | ||||
|         result = BlogPost.objects.get(author__name=user.name) | ||||
|         self.assertTrue(isinstance(result.author, User)) | ||||
|         self.assertIsInstance(result.author, User) | ||||
|         self.assertEqual(result.author.name, 'Test User') | ||||
|  | ||||
|         result = BlogPost.objects.get(author={'name': user.name}) | ||||
|         self.assertTrue(isinstance(result.author, User)) | ||||
|         self.assertIsInstance(result.author, User) | ||||
|         self.assertEqual(result.author.name, 'Test User') | ||||
|  | ||||
|         # Fails, since the string is not a type that is able to represent the | ||||
| @@ -1462,7 +1474,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|         code_chunks = ['doc["cmnts"];', 'doc["doc-name"],', | ||||
|                        'doc["cmnts"][i]["body"]'] | ||||
|         for chunk in code_chunks: | ||||
|             self.assertTrue(chunk in sub_code) | ||||
|             self.assertIn(chunk, sub_code) | ||||
|  | ||||
|         results = BlogPost.objects.exec_js(code) | ||||
|         expected_results = [ | ||||
| @@ -1852,21 +1864,16 @@ class QuerySetTest(unittest.TestCase): | ||||
|         self.assertEqual( | ||||
|             1, BlogPost.objects(author__in=["%s" % me.pk]).count()) | ||||
|  | ||||
|     def test_update(self): | ||||
|         """Ensure that atomic updates work properly. | ||||
|         """ | ||||
|     def test_update_intfield_operator(self): | ||||
|         class BlogPost(Document): | ||||
|             name = StringField() | ||||
|             title = StringField() | ||||
|             hits = IntField() | ||||
|             tags = ListField(StringField()) | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(name="Test Post", hits=5, tags=['test']) | ||||
|         post = BlogPost(hits=5) | ||||
|         post.save() | ||||
|  | ||||
|         BlogPost.objects.update(set__hits=10) | ||||
|         BlogPost.objects.update_one(set__hits=10) | ||||
|         post.reload() | ||||
|         self.assertEqual(post.hits, 10) | ||||
|  | ||||
| @@ -1883,13 +1890,63 @@ class QuerySetTest(unittest.TestCase): | ||||
|         post.reload() | ||||
|         self.assertEqual(post.hits, 11) | ||||
|  | ||||
|     def test_update_decimalfield_operator(self): | ||||
|         class BlogPost(Document): | ||||
|             review = DecimalField() | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(review=3.5) | ||||
|         post.save() | ||||
|  | ||||
|         BlogPost.objects.update_one(inc__review=0.1)             # test with floats | ||||
|         post.reload() | ||||
|         self.assertEqual(float(post.review), 3.6) | ||||
|  | ||||
|         BlogPost.objects.update_one(dec__review=0.1) | ||||
|         post.reload() | ||||
|         self.assertEqual(float(post.review), 3.5) | ||||
|  | ||||
|         BlogPost.objects.update_one(inc__review=Decimal(0.12))   # test with Decimal | ||||
|         post.reload() | ||||
|         self.assertEqual(float(post.review), 3.62) | ||||
|  | ||||
|         BlogPost.objects.update_one(dec__review=Decimal(0.12)) | ||||
|         post.reload() | ||||
|         self.assertEqual(float(post.review), 3.5) | ||||
|  | ||||
|     def test_update_decimalfield_operator_not_working_with_force_string(self): | ||||
|         class BlogPost(Document): | ||||
|             review = DecimalField(force_string=True) | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(review=3.5) | ||||
|         post.save() | ||||
|  | ||||
|         with self.assertRaises(OperationError): | ||||
|             BlogPost.objects.update_one(inc__review=0.1)             # test with floats | ||||
|  | ||||
|     def test_update_listfield_operator(self): | ||||
|         """Ensure that atomic updates work properly. | ||||
|         """ | ||||
|         class BlogPost(Document): | ||||
|             tags = ListField(StringField()) | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(tags=['test']) | ||||
|         post.save() | ||||
|  | ||||
|         # ListField operator | ||||
|         BlogPost.objects.update(push__tags='mongo') | ||||
|         post.reload() | ||||
|         self.assertTrue('mongo' in post.tags) | ||||
|         self.assertIn('mongo', post.tags) | ||||
|  | ||||
|         BlogPost.objects.update_one(push_all__tags=['db', 'nosql']) | ||||
|         post.reload() | ||||
|         self.assertTrue('db' in post.tags and 'nosql' in post.tags) | ||||
|         self.assertIn('db', post.tags) | ||||
|         self.assertIn('nosql', post.tags) | ||||
|  | ||||
|         tags = post.tags[:-1] | ||||
|         BlogPost.objects.update(pop__tags=1) | ||||
| @@ -1901,13 +1958,23 @@ class QuerySetTest(unittest.TestCase): | ||||
|         post.reload() | ||||
|         self.assertEqual(post.tags.count('unique'), 1) | ||||
|  | ||||
|         self.assertNotEqual(post.hits, None) | ||||
|         BlogPost.objects.update_one(unset__hits=1) | ||||
|         post.reload() | ||||
|         self.assertEqual(post.hits, None) | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|     def test_update_unset(self): | ||||
|         class BlogPost(Document): | ||||
|             title = StringField() | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(title='garbage').save() | ||||
|  | ||||
|         self.assertNotEqual(post.title, None) | ||||
|         BlogPost.objects.update_one(unset__title=1) | ||||
|         post.reload() | ||||
|         self.assertEqual(post.title, None) | ||||
|         pymongo_doc = BlogPost.objects.as_pymongo().first() | ||||
|         self.assertNotIn('title', pymongo_doc) | ||||
|  | ||||
|     @needs_mongodb_v26 | ||||
|     def test_update_push_with_position(self): | ||||
|         """Ensure that the 'push' update with position works properly. | ||||
| @@ -1934,6 +2001,21 @@ class QuerySetTest(unittest.TestCase): | ||||
|         post.reload() | ||||
|         self.assertEqual(post.tags, ['scala', 'mongodb', 'python', 'java']) | ||||
|  | ||||
|     def test_update_push_list_of_list(self): | ||||
|         """Ensure that the 'push' update operation works in the list of list | ||||
|         """ | ||||
|         class BlogPost(Document): | ||||
|             slug = StringField() | ||||
|             tags = ListField() | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
|         post = BlogPost(slug="test").save() | ||||
|  | ||||
|         BlogPost.objects.filter(slug="test").update(push__tags=["value1", 123]) | ||||
|         post.reload() | ||||
|         self.assertEqual(post.tags, [["value1", 123]]) | ||||
|  | ||||
|     def test_update_push_and_pull_add_to_set(self): | ||||
|         """Ensure that the 'pull' update operation works correctly. | ||||
|         """ | ||||
| @@ -2076,6 +2158,23 @@ class QuerySetTest(unittest.TestCase): | ||||
|             Site.objects(id=s.id).update_one( | ||||
|                 pull_all__collaborators__helpful__user=['Ross']) | ||||
|  | ||||
|     def test_pull_in_genericembedded_field(self): | ||||
|  | ||||
|         class Foo(EmbeddedDocument): | ||||
|             name = StringField() | ||||
|  | ||||
|         class Bar(Document): | ||||
|             foos = ListField(GenericEmbeddedDocumentField( | ||||
|                 choices=[Foo, ])) | ||||
|  | ||||
|         Bar.drop_collection() | ||||
|  | ||||
|         foo = Foo(name="bar") | ||||
|         bar = Bar(foos=[foo]).save() | ||||
|         Bar.objects(id=bar.id).update(pull__foos=foo) | ||||
|         bar.reload() | ||||
|         self.assertEqual(len(bar.foos), 0) | ||||
|  | ||||
|     def test_update_one_pop_generic_reference(self): | ||||
|  | ||||
|         class BlogTag(Document): | ||||
| @@ -2169,6 +2268,24 @@ class QuerySetTest(unittest.TestCase): | ||||
|         self.assertEqual(message.authors[1].name, "Ross") | ||||
|         self.assertEqual(message.authors[2].name, "Adam") | ||||
|  | ||||
|     def test_set_generic_embedded_documents(self): | ||||
|  | ||||
|         class Bar(EmbeddedDocument): | ||||
|             name = StringField() | ||||
|  | ||||
|         class User(Document): | ||||
|             username = StringField() | ||||
|             bar = GenericEmbeddedDocumentField(choices=[Bar,]) | ||||
|  | ||||
|         User.drop_collection() | ||||
|  | ||||
|         User(username='abc').save() | ||||
|         User.objects(username='abc').update( | ||||
|             set__bar=Bar(name='test'), upsert=True) | ||||
|  | ||||
|         user = User.objects(username='abc').first() | ||||
|         self.assertEqual(user.bar.name, "test") | ||||
|  | ||||
|     def test_reload_embedded_docs_instance(self): | ||||
|  | ||||
|         class SubDoc(EmbeddedDocument): | ||||
| @@ -2338,14 +2455,19 @@ class QuerySetTest(unittest.TestCase): | ||||
|             age = IntField() | ||||
|  | ||||
|         with db_ops_tracker() as q: | ||||
|             adult = (User.objects.filter(age__gte=18) | ||||
|             adult1 = (User.objects.filter(age__gte=18) | ||||
|                 .comment('looking for an adult') | ||||
|                 .first()) | ||||
|  | ||||
|             adult2 = (User.objects.comment('looking for an adult') | ||||
|                 .filter(age__gte=18) | ||||
|                 .first()) | ||||
|  | ||||
|             ops = q.get_ops() | ||||
|             self.assertEqual(len(ops), 1) | ||||
|             op = ops[0] | ||||
|             self.assertEqual(op['query']['$query'], {'age': {'$gte': 18}}) | ||||
|             self.assertEqual(op['query']['$comment'], 'looking for an adult') | ||||
|             self.assertEqual(len(ops), 2) | ||||
|             for op in ops: | ||||
|                 self.assertEqual(op['query']['$query'], {'age': {'$gte': 18}}) | ||||
|                 self.assertEqual(op['query']['$comment'], 'looking for an adult') | ||||
|  | ||||
|     def test_map_reduce(self): | ||||
|         """Ensure map/reduce is both mapping and reducing. | ||||
| @@ -3157,8 +3279,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         News.drop_collection() | ||||
|         info = News.objects._collection.index_information() | ||||
|         self.assertTrue('title_text_content_text' in info) | ||||
|         self.assertTrue('textIndexVersion' in info['title_text_content_text']) | ||||
|         self.assertIn('title_text_content_text', info) | ||||
|         self.assertIn('textIndexVersion', info['title_text_content_text']) | ||||
|  | ||||
|         News(title="Neymar quebrou a vertebra", | ||||
|              content="O Brasil sofre com a perda de Neymar").save() | ||||
| @@ -3192,15 +3314,15 @@ class QuerySetTest(unittest.TestCase): | ||||
|                 '$search': 'dilma', '$language': 'pt'}, | ||||
|                 'is_active': False}) | ||||
|  | ||||
|         self.assertEqual(new.is_active, False) | ||||
|         self.assertTrue('dilma' in new.content) | ||||
|         self.assertTrue('planejamento' in new.title) | ||||
|         self.assertFalse(new.is_active) | ||||
|         self.assertIn('dilma', new.content) | ||||
|         self.assertIn('planejamento', new.title) | ||||
|  | ||||
|         query = News.objects.search_text("candidata") | ||||
|         self.assertEqual(query._search_text, "candidata") | ||||
|         new = query.first() | ||||
|  | ||||
|         self.assertTrue(isinstance(new.get_text_score(), float)) | ||||
|         self.assertIsInstance(new.get_text_score(), float) | ||||
|  | ||||
|         # count | ||||
|         query = News.objects.search_text('brasil').order_by('$text_score') | ||||
| @@ -3495,39 +3617,12 @@ class QuerySetTest(unittest.TestCase): | ||||
|         Group.objects(id=group.id).update(set__members=[user1, user2]) | ||||
|         group.reload() | ||||
|  | ||||
|         self.assertTrue(len(group.members) == 2) | ||||
|         self.assertEqual(len(group.members), 2) | ||||
|         self.assertEqual(group.members[0].name, user1.name) | ||||
|         self.assertEqual(group.members[1].name, user2.name) | ||||
|  | ||||
|         Group.drop_collection() | ||||
|  | ||||
|     def test_dict_with_custom_baseclass(self): | ||||
|         """Ensure DictField working with custom base clases. | ||||
|         """ | ||||
|         class Test(Document): | ||||
|             testdict = DictField() | ||||
|  | ||||
|         Test.drop_collection() | ||||
|  | ||||
|         t = Test(testdict={'f': 'Value'}) | ||||
|         t.save() | ||||
|  | ||||
|         self.assertEqual( | ||||
|             Test.objects(testdict__f__startswith='Val').count(), 1) | ||||
|         self.assertEqual(Test.objects(testdict__f='Value').count(), 1) | ||||
|         Test.drop_collection() | ||||
|  | ||||
|         class Test(Document): | ||||
|             testdict = DictField(basecls=StringField) | ||||
|  | ||||
|         t = Test(testdict={'f': 'Value'}) | ||||
|         t.save() | ||||
|  | ||||
|         self.assertEqual(Test.objects(testdict__f='Value').count(), 1) | ||||
|         self.assertEqual( | ||||
|             Test.objects(testdict__f__startswith='Val').count(), 1) | ||||
|         Test.drop_collection() | ||||
|  | ||||
|     def test_bulk(self): | ||||
|         """Ensure bulk querying by object id returns a proper dict. | ||||
|         """ | ||||
| @@ -3553,13 +3648,13 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         self.assertEqual(len(objects), 3) | ||||
|  | ||||
|         self.assertTrue(post_1.id in objects) | ||||
|         self.assertTrue(post_2.id in objects) | ||||
|         self.assertTrue(post_5.id in objects) | ||||
|         self.assertIn(post_1.id, objects) | ||||
|         self.assertIn(post_2.id, objects) | ||||
|         self.assertIn(post_5.id, objects) | ||||
|  | ||||
|         self.assertTrue(objects[post_1.id].title == post_1.title) | ||||
|         self.assertTrue(objects[post_2.id].title == post_2.title) | ||||
|         self.assertTrue(objects[post_5.id].title == post_5.title) | ||||
|         self.assertEqual(objects[post_1.id].title, post_1.title) | ||||
|         self.assertEqual(objects[post_2.id].title, post_2.title) | ||||
|         self.assertEqual(objects[post_5.id].title, post_5.title) | ||||
|  | ||||
|         BlogPost.drop_collection() | ||||
|  | ||||
| @@ -3579,7 +3674,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         Post.drop_collection() | ||||
|  | ||||
|         self.assertTrue(isinstance(Post.objects, CustomQuerySet)) | ||||
|         self.assertIsInstance(Post.objects, CustomQuerySet) | ||||
|         self.assertFalse(Post.objects.not_empty()) | ||||
|  | ||||
|         Post().save() | ||||
| @@ -3604,7 +3699,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         Post.drop_collection() | ||||
|  | ||||
|         self.assertTrue(isinstance(Post.objects, CustomQuerySet)) | ||||
|         self.assertIsInstance(Post.objects, CustomQuerySet) | ||||
|         self.assertFalse(Post.objects.not_empty()) | ||||
|  | ||||
|         Post().save() | ||||
| @@ -3651,7 +3746,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             pass | ||||
|  | ||||
|         Post.drop_collection() | ||||
|         self.assertTrue(isinstance(Post.objects, CustomQuerySet)) | ||||
|         self.assertIsInstance(Post.objects, CustomQuerySet) | ||||
|         self.assertFalse(Post.objects.not_empty()) | ||||
|  | ||||
|         Post().save() | ||||
| @@ -3679,7 +3774,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             pass | ||||
|  | ||||
|         Post.drop_collection() | ||||
|         self.assertTrue(isinstance(Post.objects, CustomQuerySet)) | ||||
|         self.assertIsInstance(Post.objects, CustomQuerySet) | ||||
|         self.assertFalse(Post.objects.not_empty()) | ||||
|  | ||||
|         Post().save() | ||||
| @@ -3770,17 +3865,17 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         test = Number.objects | ||||
|         test2 = test.clone() | ||||
|         self.assertFalse(test == test2) | ||||
|         self.assertNotEqual(test, test2) | ||||
|         self.assertEqual(test.count(), test2.count()) | ||||
|  | ||||
|         test = test.filter(n__gt=11) | ||||
|         test2 = test.clone() | ||||
|         self.assertFalse(test == test2) | ||||
|         self.assertNotEqual(test, test2) | ||||
|         self.assertEqual(test.count(), test2.count()) | ||||
|  | ||||
|         test = test.limit(10) | ||||
|         test2 = test.clone() | ||||
|         self.assertFalse(test == test2) | ||||
|         self.assertNotEqual(test, test2) | ||||
|         self.assertEqual(test.count(), test2.count()) | ||||
|  | ||||
|         Number.drop_collection() | ||||
| @@ -3870,7 +3965,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|                  value.get('unique', False), | ||||
|                  value.get('sparse', False)) | ||||
|                 for key, value in info.iteritems()] | ||||
|         self.assertTrue(([('_cls', 1), ('message', 1)], False, False) in info) | ||||
|         self.assertIn(([('_cls', 1), ('message', 1)], False, False), info) | ||||
|  | ||||
|     def test_where(self): | ||||
|         """Ensure that where clauses work. | ||||
| @@ -3894,13 +3989,13 @@ class QuerySetTest(unittest.TestCase): | ||||
|             'this["fielda"] >= this["fieldb"]', query._where_clause) | ||||
|         results = list(query) | ||||
|         self.assertEqual(2, len(results)) | ||||
|         self.assertTrue(a in results) | ||||
|         self.assertTrue(c in results) | ||||
|         self.assertIn(a, results) | ||||
|         self.assertIn(c, results) | ||||
|  | ||||
|         query = IntPair.objects.where('this[~fielda] == this[~fieldb]') | ||||
|         results = list(query) | ||||
|         self.assertEqual(1, len(results)) | ||||
|         self.assertTrue(a in results) | ||||
|         self.assertIn(a, results) | ||||
|  | ||||
|         query = IntPair.objects.where( | ||||
|             'function() { return this[~fielda] >= this[~fieldb] }') | ||||
| @@ -3908,8 +4003,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|             'function() { return this["fielda"] >= this["fieldb"] }', query._where_clause) | ||||
|         results = list(query) | ||||
|         self.assertEqual(2, len(results)) | ||||
|         self.assertTrue(a in results) | ||||
|         self.assertTrue(c in results) | ||||
|         self.assertIn(a, results) | ||||
|         self.assertIn(c, results) | ||||
|  | ||||
|         with self.assertRaises(TypeError): | ||||
|             list(IntPair.objects.where(fielda__gte=3)) | ||||
| @@ -4291,7 +4386,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         Test.drop_collection() | ||||
|         Test.objects(test='foo').update_one(upsert=True, set__test='foo') | ||||
|         self.assertFalse('_cls' in Test._collection.find_one()) | ||||
|         self.assertNotIn('_cls', Test._collection.find_one()) | ||||
|  | ||||
|         class Test(Document): | ||||
|             meta = {'allow_inheritance': True} | ||||
| @@ -4300,7 +4395,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|         Test.drop_collection() | ||||
|  | ||||
|         Test.objects(test='foo').update_one(upsert=True, set__test='foo') | ||||
|         self.assertTrue('_cls' in Test._collection.find_one()) | ||||
|         self.assertIn('_cls', Test._collection.find_one()) | ||||
|  | ||||
|     def test_update_upsert_looks_like_a_digit(self): | ||||
|         class MyDoc(DynamicDocument): | ||||
| @@ -4384,6 +4479,25 @@ class QuerySetTest(unittest.TestCase): | ||||
|         self.assertEqual(bars._cursor._Cursor__read_preference, | ||||
|                          ReadPreference.SECONDARY_PREFERRED) | ||||
|  | ||||
|     @needs_mongodb_v26 | ||||
|     def test_read_preference_aggregation_framework(self): | ||||
|         class Bar(Document): | ||||
|             txt = StringField() | ||||
|  | ||||
|             meta = { | ||||
|                 'indexes': ['txt'] | ||||
|             } | ||||
|         # Aggregates with read_preference | ||||
|         bars = Bar.objects \ | ||||
|                     .read_preference(ReadPreference.SECONDARY_PREFERRED) \ | ||||
|                     .aggregate() | ||||
|         if IS_PYMONGO_3: | ||||
|             self.assertEqual(bars._CommandCursor__collection.read_preference, | ||||
|                              ReadPreference.SECONDARY_PREFERRED) | ||||
|         else: | ||||
|             self.assertNotEqual(bars._CommandCursor__collection.read_preference, | ||||
|                              ReadPreference.SECONDARY_PREFERRED) | ||||
|  | ||||
|     def test_json_simple(self): | ||||
|  | ||||
|         class Embedded(EmbeddedDocument): | ||||
| @@ -4493,8 +4607,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         users = User.objects.only('name', 'price').as_pymongo() | ||||
|         results = list(users) | ||||
|         self.assertTrue(isinstance(results[0], dict)) | ||||
|         self.assertTrue(isinstance(results[1], dict)) | ||||
|         self.assertIsInstance(results[0], dict) | ||||
|         self.assertIsInstance(results[1], dict) | ||||
|         self.assertEqual(results[0]['name'], 'Bob Dole') | ||||
|         self.assertEqual(results[0]['price'], 1.11) | ||||
|         self.assertEqual(results[1]['name'], 'Barack Obama') | ||||
| @@ -4502,8 +4616,8 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         users = User.objects.only('name', 'last_login').as_pymongo() | ||||
|         results = list(users) | ||||
|         self.assertTrue(isinstance(results[0], dict)) | ||||
|         self.assertTrue(isinstance(results[1], dict)) | ||||
|         self.assertIsInstance(results[0], dict) | ||||
|         self.assertIsInstance(results[1], dict) | ||||
|         self.assertEqual(results[0], { | ||||
|             'name': 'Bob Dole' | ||||
|         }) | ||||
| @@ -4560,12 +4674,10 @@ class QuerySetTest(unittest.TestCase): | ||||
|         User(name="Bob Dole", organization=whitehouse).save() | ||||
|  | ||||
|         qs = User.objects() | ||||
|         self.assertTrue(isinstance(qs.first().organization, Organization)) | ||||
|         self.assertFalse(isinstance(qs.no_dereference().first().organization, | ||||
|                                     Organization)) | ||||
|         self.assertFalse(isinstance(qs.no_dereference().get().organization, | ||||
|                                     Organization)) | ||||
|         self.assertTrue(isinstance(qs.first().organization, Organization)) | ||||
|         self.assertIsInstance(qs.first().organization, Organization) | ||||
|         self.assertNotIsInstance(qs.no_dereference().first().organization, Organization) | ||||
|         self.assertNotIsInstance(qs.no_dereference().get().organization, Organization) | ||||
|         self.assertIsInstance(qs.first().organization, Organization) | ||||
|  | ||||
|     def test_no_dereference_embedded_doc(self): | ||||
|  | ||||
| @@ -4598,9 +4710,9 @@ class QuerySetTest(unittest.TestCase): | ||||
|  | ||||
|         result = Organization.objects().no_dereference().first() | ||||
|  | ||||
|         self.assertTrue(isinstance(result.admin[0], (DBRef, ObjectId))) | ||||
|         self.assertTrue(isinstance(result.member.user, (DBRef, ObjectId))) | ||||
|         self.assertTrue(isinstance(result.members[0].user, (DBRef, ObjectId))) | ||||
|         self.assertIsInstance(result.admin[0], (DBRef, ObjectId)) | ||||
|         self.assertIsInstance(result.member.user, (DBRef, ObjectId)) | ||||
|         self.assertIsInstance(result.members[0].user, (DBRef, ObjectId)) | ||||
|  | ||||
|     def test_cached_queryset(self): | ||||
|         class Person(Document): | ||||
| @@ -4641,18 +4753,27 @@ class QuerySetTest(unittest.TestCase): | ||||
|         for i in range(100): | ||||
|             Person(name="No: %s" % i).save() | ||||
|  | ||||
|         with query_counter() as q: | ||||
|             self.assertEqual(q, 0) | ||||
|             people = Person.objects.no_cache() | ||||
|             with query_counter() as q: | ||||
|                 try: | ||||
|                     self.assertEqual(q, 0) | ||||
|                     people = Person.objects.no_cache() | ||||
|  | ||||
|             [x for x in people] | ||||
|             self.assertEqual(q, 1) | ||||
|                     [x for x in people] | ||||
|                     self.assertEqual(q, 1) | ||||
|  | ||||
|             list(people) | ||||
|             self.assertEqual(q, 2) | ||||
|                     list(people) | ||||
|                     self.assertEqual(q, 2) | ||||
|  | ||||
|                     people.count() | ||||
|                     self.assertEqual(q, 3) | ||||
|                 except AssertionError as exc: | ||||
|                     db = get_db() | ||||
|                     msg = '' | ||||
|                     for q in list(db.system.profile.find())[-50:]: | ||||
|                         msg += str([q['ts'], q['ns'], q.get('query'), q['op']])+'\n' | ||||
|                         msg += str(q) | ||||
|                     raise AssertionError(str(exc) + '\n'+msg) | ||||
|  | ||||
|             people.count() | ||||
|             self.assertEqual(q, 3) | ||||
|  | ||||
|     def test_cache_not_cloned(self): | ||||
|  | ||||
| @@ -4795,6 +4916,30 @@ class QuerySetTest(unittest.TestCase): | ||||
|         for obj in C.objects.no_sub_classes(): | ||||
|             self.assertEqual(obj.__class__, C) | ||||
|  | ||||
|     def test_query_generic_embedded_document(self): | ||||
|         """Ensure that querying sub field on generic_embedded_field works | ||||
|         """ | ||||
|         class A(EmbeddedDocument): | ||||
|             a_name = StringField() | ||||
|  | ||||
|         class B(EmbeddedDocument): | ||||
|             b_name = StringField() | ||||
|  | ||||
|         class Doc(Document): | ||||
|             document = GenericEmbeddedDocumentField(choices=(A, B)) | ||||
|  | ||||
|         Doc.drop_collection() | ||||
|         Doc(document=A(a_name='A doc')).save() | ||||
|         Doc(document=B(b_name='B doc')).save() | ||||
|  | ||||
|         # Using raw in filter working fine | ||||
|         self.assertEqual(Doc.objects( | ||||
|             __raw__={'document.a_name': 'A doc'}).count(), 1) | ||||
|         self.assertEqual(Doc.objects( | ||||
|             __raw__={'document.b_name': 'B doc'}).count(), 1) | ||||
|         self.assertEqual(Doc.objects(document__a_name='A doc').count(), 1) | ||||
|         self.assertEqual(Doc.objects(document__b_name='B doc').count(), 1) | ||||
|  | ||||
|     def test_query_reference_to_custom_pk_doc(self): | ||||
|  | ||||
|         class A(Document): | ||||
| @@ -4919,7 +5064,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             op = q.db.system.profile.find({"ns": | ||||
|                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] | ||||
|  | ||||
|             self.assertFalse('$orderby' in op['query'], | ||||
|             self.assertNotIn('$orderby', op['query'], | ||||
|                              'BaseQuerySet cannot use orderby in if stmt') | ||||
|  | ||||
|         with query_counter() as p: | ||||
| @@ -4930,8 +5075,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             op = p.db.system.profile.find({"ns": | ||||
|                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] | ||||
|  | ||||
|             self.assertTrue('$orderby' in op['query'], | ||||
|                             'BaseQuerySet cannot remove orderby in for loop') | ||||
|             self.assertIn('$orderby', op['query'], 'BaseQuerySet cannot remove orderby in for loop') | ||||
|  | ||||
|     def test_bool_with_ordering_from_meta_dict(self): | ||||
|  | ||||
| @@ -4955,7 +5099,7 @@ class QuerySetTest(unittest.TestCase): | ||||
|             op = q.db.system.profile.find({"ns": | ||||
|                                            {"$ne": "%s.system.indexes" % q.db.name}})[0] | ||||
|  | ||||
|             self.assertFalse('$orderby' in op['query'], | ||||
|             self.assertNotIn('$orderby', op['query'], | ||||
|                              'BaseQuerySet must remove orderby from meta in boolen test') | ||||
|  | ||||
|             self.assertEqual(Person.objects.first().name, 'A') | ||||
|   | ||||
		Reference in New Issue
	
	Block a user