Merge pull request #1703 from erdenezul/invalid_instance_genericembedded

fix validation error for invalid embedded document instance #1067
This commit is contained in:
Emmanuel Leblond 2017-12-22 12:23:31 +01:00 committed by GitHub
commit ff408c604b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 2 deletions

View File

@ -7,7 +7,7 @@ dev
- Subfield resolve error in generic_emdedded_document query #1651 #1652 - Subfield resolve error in generic_emdedded_document query #1651 #1652
- use each modifier only with $position #1673 #1675 - use each modifier only with $position #1673 #1675
- Improve LazyReferenceField and GenericLazyReferenceField with nested fields #1704 - Improve LazyReferenceField and GenericLazyReferenceField with nested fields #1704
- Fix validation error instance in GenericEmbeddedDocumentField #1067
Changes in 0.15.0 Changes in 0.15.0
================= =================

View File

@ -689,6 +689,11 @@ class GenericEmbeddedDocumentField(BaseField):
return value return value
def validate(self, value, clean=True): def validate(self, value, clean=True):
if self.choices and isinstance(value, SON):
for choice in self.choices:
if value['_cls'] == choice._class_name:
return True
if not isinstance(value, EmbeddedDocument): if not isinstance(value, EmbeddedDocument):
self.error('Invalid embedded document instance provided to an ' self.error('Invalid embedded document instance provided to an '
'GenericEmbeddedDocumentField') 'GenericEmbeddedDocumentField')
@ -706,7 +711,6 @@ class GenericEmbeddedDocumentField(BaseField):
def to_mongo(self, document, use_db_field=True, fields=None): def to_mongo(self, document, use_db_field=True, fields=None):
if document is None: if document is None:
return None return None
data = document.to_mongo(use_db_field, fields) data = document.to_mongo(use_db_field, fields)
if '_cls' not in data: if '_cls' not in data:
data['_cls'] = document._class_name data['_cls'] = document._class_name

View File

@ -2086,6 +2086,23 @@ class QuerySetTest(unittest.TestCase):
Site.objects(id=s.id).update_one( Site.objects(id=s.id).update_one(
pull_all__collaborators__helpful__user=['Ross']) pull_all__collaborators__helpful__user=['Ross'])
def test_pull_in_genericembedded_field(self):
class Foo(EmbeddedDocument):
name = StringField()
class Bar(Document):
foos = ListField(GenericEmbeddedDocumentField(
choices=[Foo, ]))
Bar.drop_collection()
foo = Foo(name="bar")
bar = Bar(foos=[foo]).save()
Bar.objects(id=bar.id).update(pull__foos=foo)
bar.reload()
self.assertEqual(len(bar.foos), 0)
def test_update_one_pop_generic_reference(self): def test_update_one_pop_generic_reference(self):
class BlogTag(Document): class BlogTag(Document):
@ -2179,6 +2196,24 @@ class QuerySetTest(unittest.TestCase):
self.assertEqual(message.authors[1].name, "Ross") self.assertEqual(message.authors[1].name, "Ross")
self.assertEqual(message.authors[2].name, "Adam") self.assertEqual(message.authors[2].name, "Adam")
def test_set_generic_embedded_documents(self):
class Bar(EmbeddedDocument):
name = StringField()
class User(Document):
username = StringField()
bar = GenericEmbeddedDocumentField(choices=[Bar,])
User.drop_collection()
User(username='abc').save()
User.objects(username='abc').update(
set__bar=Bar(name='test'), upsert=True)
user = User.objects(username='abc').first()
self.assertEqual(user.bar.name, "test")
def test_reload_embedded_docs_instance(self): def test_reload_embedded_docs_instance(self):
class SubDoc(EmbeddedDocument): class SubDoc(EmbeddedDocument):