fix validation for a nested DictField
This commit is contained in:
parent
bcbe740598
commit
89785da1c5
@ -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)
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user