diff --git a/mongoengine/fields.py b/mongoengine/fields.py index d1f9b665..11366dd0 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -449,7 +449,17 @@ class DictField(BaseField): 'contain "." or "$" characters') def lookup_member(self, member_name): - return self.basecls(db_field=member_name) + return DictField(basecls=self.basecls, db_field=member_name) + + def prepare_query_value(self, op, value): + match_operators = ['contains', 'icontains', 'startswith', + 'istartswith', 'endswith', 'iendswith', + 'exact', 'iexact'] + + if op in match_operators and isinstance(value, basestring): + return StringField().prepare_query_value(op, value) + + return super(DictField,self).prepare_query_value(op, value) class MapField(BaseField): diff --git a/tests/fields.py b/tests/fields.py index 62bd3a1f..00b1c886 100644 --- a/tests/fields.py +++ b/tests/fields.py @@ -262,12 +262,14 @@ class FieldTest(unittest.TestCase): BlogPost.drop_collection() - def test_dict_validation(self): + def test_dict_field(self): """Ensure that dict types work as expected. """ class BlogPost(Document): info = DictField() + BlogPost.drop_collection() + post = BlogPost() post.info = 'my post' self.assertRaises(ValidationError, post.validate) @@ -282,7 +284,24 @@ class FieldTest(unittest.TestCase): self.assertRaises(ValidationError, post.validate) post.info = {'title': 'test'} - post.validate() + post.save() + + post = BlogPost() + post.info = {'details': {'test': 'test'}} + post.save() + + post = BlogPost() + post.info = {'details': {'test': 3}} + post.save() + + self.assertEquals(BlogPost.objects.count(), 3) + self.assertEquals(BlogPost.objects.filter(info__title__exact='test').count(), 1) + self.assertEquals(BlogPost.objects.filter(info__details__test__exact='test').count(), 1) + + # Confirm handles non strings or non existing keys + self.assertEquals(BlogPost.objects.filter(info__details__test__exact=5).count(), 0) + self.assertEquals(BlogPost.objects.filter(info__made_up__test__exact='test').count(), 0) + BlogPost.drop_collection() def test_embedded_document_validation(self): """Ensure that invalid embedded documents cannot be assigned to diff --git a/tests/queryset.py b/tests/queryset.py index 777f9e36..6c0b686f 100644 --- a/tests/queryset.py +++ b/tests/queryset.py @@ -1539,7 +1539,7 @@ class QuerySetTest(unittest.TestCase): t = Test(testdict={'f': 'Value'}) t.save() - self.assertEqual(len(Test.objects(testdict__f__startswith='Val')), 0) + self.assertEqual(len(Test.objects(testdict__f__startswith='Val')), 1) self.assertEqual(len(Test.objects(testdict__f='Value')), 1) Test.drop_collection()