Merge pull request #1877 from bagerard/improve_ComplexField_validation_edge_case
Handles edge case when EmbeddedDocumentListField receives a Document and not a list
This commit is contained in:
commit
1887f5b7e7
@ -314,11 +314,16 @@ class ComplexBaseField(BaseField):
|
||||
if hasattr(value, 'to_python'):
|
||||
return value.to_python()
|
||||
|
||||
BaseDocument = _import_class('BaseDocument')
|
||||
if isinstance(value, BaseDocument):
|
||||
# Something is wrong, return the value as it is
|
||||
return value
|
||||
|
||||
is_list = False
|
||||
if not hasattr(value, 'items'):
|
||||
try:
|
||||
is_list = True
|
||||
value = {k: v for k, v in enumerate(value)}
|
||||
value = {idx: v for idx, v in enumerate(value)}
|
||||
except TypeError: # Not iterable return the value
|
||||
return value
|
||||
|
||||
|
@ -3743,7 +3743,7 @@ class FieldTest(MongoDBTestCase):
|
||||
assert isinstance(doc.field, ToEmbedChild)
|
||||
assert doc.field == to_embed_child
|
||||
|
||||
def test_invalid_dict_value(self):
|
||||
def test_dict_field_invalid_dict_value(self):
|
||||
class DictFieldTest(Document):
|
||||
dictionary = DictField(required=True)
|
||||
|
||||
@ -3757,6 +3757,22 @@ class FieldTest(MongoDBTestCase):
|
||||
test.dictionary # Just access to test getter
|
||||
self.assertRaises(ValidationError, test.validate)
|
||||
|
||||
def test_dict_field_raises_validation_error_if_wrongly_assign_embedded_doc(self):
|
||||
class DictFieldTest(Document):
|
||||
dictionary = DictField(required=True)
|
||||
|
||||
DictFieldTest.drop_collection()
|
||||
|
||||
class Embedded(EmbeddedDocument):
|
||||
name = StringField()
|
||||
|
||||
embed = Embedded(name='garbage')
|
||||
doc = DictFieldTest(dictionary=embed)
|
||||
with self.assertRaises(ValidationError) as ctx_err:
|
||||
doc.validate()
|
||||
self.assertIn("'dictionary'", str(ctx_err.exception))
|
||||
self.assertIn('Only dictionaries may be used in a DictField', str(ctx_err.exception))
|
||||
|
||||
def test_cls_field(self):
|
||||
class Animal(Document):
|
||||
meta = {'allow_inheritance': True}
|
||||
@ -3855,6 +3871,28 @@ class EmbeddedDocumentListFieldTestCase(MongoDBTestCase):
|
||||
self.Comments(author='user3', message='message1')
|
||||
]).save()
|
||||
|
||||
def test_fails_upon_validate_if_provide_a_doc_instead_of_a_list_of_doc(self):
|
||||
# Relates to Issue #1464
|
||||
comment = self.Comments(author='John')
|
||||
|
||||
class Title(Document):
|
||||
content = StringField()
|
||||
|
||||
# Test with an embeddedDocument instead of a list(embeddedDocument)
|
||||
# It's an edge case but it used to fail with a vague error, making it difficult to troubleshoot it
|
||||
post = self.BlogPost(comments=comment)
|
||||
with self.assertRaises(ValidationError) as ctx_err:
|
||||
post.validate()
|
||||
self.assertIn("'comments'", str(ctx_err.exception))
|
||||
self.assertIn('Only lists and tuples may be used in a list field', str(ctx_err.exception))
|
||||
|
||||
# Test with a Document
|
||||
post = self.BlogPost(comments=Title(content='garbage'))
|
||||
with self.assertRaises(ValidationError) as e:
|
||||
post.validate()
|
||||
self.assertIn("'comments'", str(ctx_err.exception))
|
||||
self.assertIn('Only lists and tuples may be used in a list field', str(ctx_err.exception))
|
||||
|
||||
def test_no_keyword_filter(self):
|
||||
"""
|
||||
Tests the filter method of a List of Embedded Documents
|
||||
|
Loading…
x
Reference in New Issue
Block a user