Merge pull request #1975 from bagerard/dictfield-key-with-dollar-char__clone

PR CLONE - Dictfield key with dollar char  clone
This commit is contained in:
Bastien Gérard 2018-12-27 23:02:00 +01:00 committed by GitHub
commit fce994ea7f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 3 deletions

View File

@ -944,7 +944,7 @@ def key_has_dot_or_dollar(d):
dictionary contains a dot or a dollar sign. dictionary contains a dot or a dollar sign.
""" """
for k, v in d.items(): for k, v in d.items():
if ('.' in k or '$' in k) or (isinstance(v, dict) and key_has_dot_or_dollar(v)): if ('.' in k or k.startswith('$')) or (isinstance(v, dict) and key_has_dot_or_dollar(v)):
return True return True
@ -977,7 +977,7 @@ class DictField(ComplexBaseField):
self.error(msg) self.error(msg)
if key_has_dot_or_dollar(value): 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 startswith "$" characters')
super(DictField, self).validate(value) super(DictField, self).validate(value)
def lookup_member(self, member_name): def lookup_member(self, member_name):

View File

@ -1698,6 +1698,10 @@ class FieldTest(MongoDBTestCase):
post.info = {'title': 'test'} post.info = {'title': 'test'}
post.save() post.save()
post = BlogPost()
post.info = {'title' : 'dollar_sign', 'details' : {'te$t' : 'test'} }
post.save()
post = BlogPost() post = BlogPost()
post.info = {'details': {'test': 'test'}} post.info = {'details': {'test': 'test'}}
post.save() post.save()
@ -1706,12 +1710,15 @@ class FieldTest(MongoDBTestCase):
post.info = {'details': {'test': 3}} post.info = {'details': {'test': 3}}
post.save() post.save()
self.assertEqual(BlogPost.objects.count(), 3) self.assertEqual(BlogPost.objects.count(), 4)
self.assertEqual( self.assertEqual(
BlogPost.objects.filter(info__title__exact='test').count(), 1) BlogPost.objects.filter(info__title__exact='test').count(), 1)
self.assertEqual( self.assertEqual(
BlogPost.objects.filter(info__details__test__exact='test').count(), 1) BlogPost.objects.filter(info__details__test__exact='test').count(), 1)
post = BlogPost.objects.filter(info__title__exact='dollar_sign').first()
self.assertIn('te$t', post['info']['details'])
# Confirm handles non strings or non existing keys # Confirm handles non strings or non existing keys
self.assertEqual( self.assertEqual(
BlogPost.objects.filter(info__details__test__exact=5).count(), 0) BlogPost.objects.filter(info__details__test__exact=5).count(), 0)