Merge pull request #468 from elasticsales/fix-dict-validation
Fix validation for a nested DictField
This commit is contained in:
		| @@ -735,6 +735,21 @@ class SortedListField(ListField): | |||||||
|                           reverse=self._order_reverse) |                           reverse=self._order_reverse) | ||||||
|         return sorted(value, reverse=self._order_reverse) |         return sorted(value, reverse=self._order_reverse) | ||||||
|  |  | ||||||
|  | def key_not_string(d): | ||||||
|  |     """ Helper function to recursively determine if any key in a dictionary is | ||||||
|  |     not a string. | ||||||
|  |     """ | ||||||
|  |     for k, v in d.items(): | ||||||
|  |         if not isinstance(k, basestring) or (isinstance(v, dict) and key_not_string(v)): | ||||||
|  |             return True | ||||||
|  |  | ||||||
|  | def key_has_dot_or_dollar(d): | ||||||
|  |     """ Helper function to recursively determine if any key in a dictionary | ||||||
|  |     contains a dot or a dollar sign. | ||||||
|  |     """ | ||||||
|  |     for k, v in d.items(): | ||||||
|  |         if ('.' in k or '$' in k) or (isinstance(v, dict) and key_has_dot_or_dollar(v)): | ||||||
|  |             return True | ||||||
|  |  | ||||||
| class DictField(ComplexBaseField): | class DictField(ComplexBaseField): | ||||||
|     """A dictionary field that wraps a standard Python dictionary. This is |     """A dictionary field that wraps a standard Python dictionary. This is | ||||||
| @@ -761,11 +776,11 @@ class DictField(ComplexBaseField): | |||||||
|         if not isinstance(value, dict): |         if not isinstance(value, dict): | ||||||
|             self.error('Only dictionaries may be used in a DictField') |             self.error('Only dictionaries may be used in a DictField') | ||||||
|  |  | ||||||
|         if any(k for k in value.keys() if not isinstance(k, basestring)): |         if key_not_string(value): | ||||||
|             msg = ("Invalid dictionary key - documents must " |             msg = ("Invalid dictionary key - documents must " | ||||||
|                    "have only string keys") |                    "have only string keys") | ||||||
|             self.error(msg) |             self.error(msg) | ||||||
|         if any(('.' in k or '$' in k) for k in value.keys()): |         if key_has_dot_or_dollar(value): | ||||||
|             self.error('Invalid dictionary key name - keys may not contain "."' |             self.error('Invalid dictionary key name - keys may not contain "."' | ||||||
|                        ' or "$" characters') |                        ' or "$" characters') | ||||||
|         super(DictField, self).validate(value) |         super(DictField, self).validate(value) | ||||||
|   | |||||||
| @@ -1109,9 +1109,15 @@ class FieldTest(unittest.TestCase): | |||||||
|         post.info = {'$title': 'test'} |         post.info = {'$title': 'test'} | ||||||
|         self.assertRaises(ValidationError, post.validate) |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|  |         post.info = {'nested': {'$title': 'test'}} | ||||||
|  |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|         post.info = {'the.title': 'test'} |         post.info = {'the.title': 'test'} | ||||||
|         self.assertRaises(ValidationError, post.validate) |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|  |         post.info = {'nested': {'the.title': 'test'}} | ||||||
|  |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|         post.info = {1: 'test'} |         post.info = {1: 'test'} | ||||||
|         self.assertRaises(ValidationError, post.validate) |         self.assertRaises(ValidationError, post.validate) | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user