Merge branch 'allow-periods-in-dict' of https://github.com/mcsimps2/mongoengine into mcsimps2-allow-periods-in-dict
This commit is contained in:
commit
b5485b16e6
1
AUTHORS
1
AUTHORS
@ -254,3 +254,4 @@ that much better:
|
|||||||
* Yurii Andrieiev (https://github.com/yandrieiev)
|
* Yurii Andrieiev (https://github.com/yandrieiev)
|
||||||
* Filip Kucharczyk (https://github.com/Pacu2)
|
* Filip Kucharczyk (https://github.com/Pacu2)
|
||||||
* Eric Timmons (https://github.com/daewok)
|
* Eric Timmons (https://github.com/daewok)
|
||||||
|
* Matthew Simpson (https://github.com/mcsimps2)
|
||||||
|
@ -41,6 +41,7 @@ from mongoengine.common import _import_class
|
|||||||
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
from mongoengine.connection import DEFAULT_CONNECTION_NAME, get_db
|
||||||
from mongoengine.document import Document, EmbeddedDocument
|
from mongoengine.document import Document, EmbeddedDocument
|
||||||
from mongoengine.errors import DoesNotExist, InvalidQueryError, ValidationError
|
from mongoengine.errors import DoesNotExist, InvalidQueryError, ValidationError
|
||||||
|
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
||||||
from mongoengine.python_support import StringIO
|
from mongoengine.python_support import StringIO
|
||||||
from mongoengine.queryset import DO_NOTHING
|
from mongoengine.queryset import DO_NOTHING
|
||||||
from mongoengine.queryset.base import BaseQuerySet
|
from mongoengine.queryset.base import BaseQuerySet
|
||||||
@ -1051,6 +1052,15 @@ def key_has_dot_or_dollar(d):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def key_starts_with_dollar(d):
|
||||||
|
"""Helper function to recursively determine if any key in a
|
||||||
|
dictionary starts with a dollar
|
||||||
|
"""
|
||||||
|
for k, v in d.items():
|
||||||
|
if (k.startswith("$")) or (isinstance(v, dict) and key_starts_with_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
|
||||||
similar to an embedded document, but the structure is not defined.
|
similar to an embedded document, but the structure is not defined.
|
||||||
@ -1077,11 +1087,18 @@ class DictField(ComplexBaseField):
|
|||||||
if key_not_string(value):
|
if key_not_string(value):
|
||||||
msg = "Invalid dictionary key - documents must have only string keys"
|
msg = "Invalid dictionary key - documents must have only string keys"
|
||||||
self.error(msg)
|
self.error(msg)
|
||||||
if key_has_dot_or_dollar(value):
|
|
||||||
|
curr_mongo_ver = get_mongodb_version()
|
||||||
|
|
||||||
|
if curr_mongo_ver < MONGODB_36 and key_has_dot_or_dollar(value):
|
||||||
self.error(
|
self.error(
|
||||||
'Invalid dictionary key name - keys may not contain "."'
|
'Invalid dictionary key name - keys may not contain "."'
|
||||||
' or startswith "$" characters'
|
' or startswith "$" characters'
|
||||||
)
|
)
|
||||||
|
elif curr_mongo_ver >= MONGODB_36 and key_starts_with_dollar(value):
|
||||||
|
self.error(
|
||||||
|
'Invalid dictionary key name - keys may not startswith "$" characters'
|
||||||
|
)
|
||||||
super(DictField, self).validate(value)
|
super(DictField, self).validate(value)
|
||||||
|
|
||||||
def lookup_member(self, member_name):
|
def lookup_member(self, member_name):
|
||||||
|
@ -3,6 +3,7 @@ import pytest
|
|||||||
|
|
||||||
from mongoengine import *
|
from mongoengine import *
|
||||||
from mongoengine.base import BaseDict
|
from mongoengine.base import BaseDict
|
||||||
|
from mongoengine.mongodb_support import MONGODB_36, get_mongodb_version
|
||||||
|
|
||||||
from tests.utils import MongoDBTestCase, get_as_pymongo
|
from tests.utils import MongoDBTestCase, get_as_pymongo
|
||||||
|
|
||||||
@ -43,11 +44,7 @@ class TestDictField(MongoDBTestCase):
|
|||||||
with pytest.raises(ValidationError):
|
with pytest.raises(ValidationError):
|
||||||
post.validate()
|
post.validate()
|
||||||
|
|
||||||
post.info = {"the.title": "test"}
|
post.info = {"$title.test": "test"}
|
||||||
with pytest.raises(ValidationError):
|
|
||||||
post.validate()
|
|
||||||
|
|
||||||
post.info = {"nested": {"the.title": "test"}}
|
|
||||||
with pytest.raises(ValidationError):
|
with pytest.raises(ValidationError):
|
||||||
post.validate()
|
post.validate()
|
||||||
|
|
||||||
@ -55,6 +52,20 @@ class TestDictField(MongoDBTestCase):
|
|||||||
with pytest.raises(ValidationError):
|
with pytest.raises(ValidationError):
|
||||||
post.validate()
|
post.validate()
|
||||||
|
|
||||||
|
post.info = {"nested": {"the.title": "test"}}
|
||||||
|
if get_mongodb_version() < MONGODB_36:
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
post.validate()
|
||||||
|
else:
|
||||||
|
post.validate()
|
||||||
|
|
||||||
|
post.info = {"dollar_and_dot": {"te$st.test": "test"}}
|
||||||
|
if get_mongodb_version() < MONGODB_36:
|
||||||
|
with pytest.raises(ValidationError):
|
||||||
|
post.validate()
|
||||||
|
else:
|
||||||
|
post.validate()
|
||||||
|
|
||||||
post.info = {"title": "test"}
|
post.info = {"title": "test"}
|
||||||
post.save()
|
post.save()
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user