fix validation for a nested DictField

This commit is contained in:
Stefan Wojcik 2013-09-16 23:50:13 -07:00
parent bcbe740598
commit 89785da1c5
2 changed files with 23 additions and 2 deletions

View File

@ -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)

View File

@ -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)