Improved DictFields
Allow searching multiple levels deep in DictFields Allow DictField entries containing strings to use matching operators Thanks again to @theojulien for the initial code #108
This commit is contained in:
		| @@ -449,7 +449,17 @@ class DictField(BaseField): | |||||||
|                                   'contain "." or "$" characters') |                                   'contain "." or "$" characters') | ||||||
|  |  | ||||||
|     def lookup_member(self, member_name): |     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): | class MapField(BaseField): | ||||||
|   | |||||||
| @@ -262,12 +262,14 @@ class FieldTest(unittest.TestCase): | |||||||
|  |  | ||||||
|         BlogPost.drop_collection() |         BlogPost.drop_collection() | ||||||
|  |  | ||||||
|     def test_dict_validation(self): |     def test_dict_field(self): | ||||||
|         """Ensure that dict types work as expected. |         """Ensure that dict types work as expected. | ||||||
|         """ |         """ | ||||||
|         class BlogPost(Document): |         class BlogPost(Document): | ||||||
|             info = DictField() |             info = DictField() | ||||||
|  |  | ||||||
|  |         BlogPost.drop_collection() | ||||||
|  |  | ||||||
|         post = BlogPost() |         post = BlogPost() | ||||||
|         post.info = 'my post' |         post.info = 'my post' | ||||||
|         self.assertRaises(ValidationError, post.validate) |         self.assertRaises(ValidationError, post.validate) | ||||||
| @@ -282,7 +284,24 @@ class FieldTest(unittest.TestCase): | |||||||
|         self.assertRaises(ValidationError, post.validate) |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|         post.info = {'title': 'test'} |         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): |     def test_embedded_document_validation(self): | ||||||
|         """Ensure that invalid embedded documents cannot be assigned to |         """Ensure that invalid embedded documents cannot be assigned to | ||||||
|   | |||||||
| @@ -1539,7 +1539,7 @@ class QuerySetTest(unittest.TestCase): | |||||||
|         t = Test(testdict={'f': 'Value'}) |         t = Test(testdict={'f': 'Value'}) | ||||||
|         t.save() |         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) |         self.assertEqual(len(Test.objects(testdict__f='Value')), 1) | ||||||
|         Test.drop_collection() |         Test.drop_collection() | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user