From 59a06a242d5d7681bac6280291ba1c97f5f2b621 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bastien=20G=C3=A9rard?= Date: Mon, 15 Oct 2018 22:32:11 +0200 Subject: [PATCH] Fix a bug when using a ReferenceField(AbstractClass) #1920 --- mongoengine/fields.py | 9 ------- tests/document/inheritance.py | 48 +++++++++++++++++++++++++++++------ 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/mongoengine/fields.py b/mongoengine/fields.py index 04e89256..284c614d 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -1176,15 +1176,6 @@ class ReferenceField(BaseField): self.error('You can only reference documents once they have been ' 'saved to the database') - if ( - self.document_type._meta.get('abstract') and - not isinstance(value, self.document_type) - ): - self.error( - '%s is not an instance of abstract reference type %s' % ( - value, self.document_type._class_name) - ) - def lookup_member(self, member_name): return self.document_type._fields.get(member_name) diff --git a/tests/document/inheritance.py b/tests/document/inheritance.py index b2ab1b52..735c68da 100644 --- a/tests/document/inheritance.py +++ b/tests/document/inheritance.py @@ -2,14 +2,11 @@ import unittest import warnings -from datetime import datetime - from tests.fixtures import Base -from mongoengine import Document, EmbeddedDocument, connect +from mongoengine import Document, EmbeddedDocument, connect, ReferenceField,\ + BooleanField, GenericReferenceField, IntField, StringField from mongoengine.connection import get_db -from mongoengine.fields import (BooleanField, GenericReferenceField, - IntField, StringField) __all__ = ('InheritanceTest', ) @@ -300,6 +297,41 @@ class InheritanceTest(unittest.TestCase): doc = Animal(name='dog') self.assertNotIn('_cls', doc.to_mongo()) + def test_using_abstract_class_in_reference_field(self): + # Ensures no regression of #1920 + class AbstractHuman(Document): + meta = {'abstract': True} + + class Dad(AbstractHuman): + name = StringField() + + class Home(Document): + dad = ReferenceField(AbstractHuman) # Referencing the abstract class + address = StringField() + + dad = Dad(name='5').save() + Home(dad=dad, address='street').save() + + home = Home.objects.first() + home.address = 'garbage' + home.save() # Was failing with ValidationError + + def test_abstract_class_referencing_self(self): + # Ensures no regression of #1920 + class Human(Document): + meta = {'abstract': True} + creator = ReferenceField('self', dbref=True) + + class User(Human): + name = StringField() + + user = User(name='John').save() + user2 = User(name='Foo', creator=user).save() + + user2 = User.objects.with_id(user2.id) + user2.name = 'Bar' + user2.save() # Was failing with ValidationError + def test_abstract_handle_ids_in_metaclass_properly(self): class City(Document): @@ -358,11 +390,11 @@ class InheritanceTest(unittest.TestCase): meta = {'abstract': True, 'allow_inheritance': False} - bkk = City(continent='asia') - self.assertEqual(None, bkk.pk) + city = City(continent='asia') + self.assertEqual(None, city.pk) # TODO: expected error? Shouldn't we create a new error type? with self.assertRaises(KeyError): - setattr(bkk, 'pk', 1) + setattr(city, 'pk', 1) def test_allow_inheritance_embedded_document(self): """Ensure embedded documents respect inheritance."""