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) | ||||
|         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): | ||||
|     """A dictionary field that wraps a standard Python dictionary. This is | ||||
| @@ -761,11 +776,11 @@ class DictField(ComplexBaseField): | ||||
|         if not isinstance(value, dict): | ||||
|             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 " | ||||
|                    "have only string keys") | ||||
|             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 "."' | ||||
|                        ' or "$" characters') | ||||
|         super(DictField, self).validate(value) | ||||
|   | ||||
| @@ -1109,9 +1109,15 @@ class FieldTest(unittest.TestCase): | ||||
|         post.info = {'$title': 'test'} | ||||
|         self.assertRaises(ValidationError, post.validate) | ||||
|  | ||||
|         post.info = {'nested': {'$title': 'test'}} | ||||
|         self.assertRaises(ValidationError, post.validate) | ||||
|  | ||||
|         post.info = {'the.title': 'test'} | ||||
|         self.assertRaises(ValidationError, post.validate) | ||||
|  | ||||
|         post.info = {'nested': {'the.title': 'test'}} | ||||
|         self.assertRaises(ValidationError, post.validate) | ||||
|  | ||||
|         post.info = {1: 'test'} | ||||
|         self.assertRaises(ValidationError, post.validate) | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user