diff --git a/docs/userguide.rst b/docs/userguide.rst index c196fd16..56bf9c97 100644 --- a/docs/userguide.rst +++ b/docs/userguide.rst @@ -213,8 +213,6 @@ saved:: >>> page = Page(title="Test Page") >>> page.id - ... - AttributeError('_id') >>> page.save() >>> page.id ObjectId('123456789abcdef000000000') diff --git a/mongoengine/base.py b/mongoengine/base.py index 2e6fe52a..cd6d8bab 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -28,12 +28,10 @@ class BaseField(object): # Get value from document instance if available, if not use default value = instance._data.get(self.name) if value is None: - if self.default is not None: - value = self.default - if callable(value): - value = value() - else: - raise AttributeError(self.name) + value = self.default + # Allow callable default values + if callable(value): + value = value() return value def __set__(self, instance, value): @@ -227,8 +225,8 @@ class BaseDocument(object): def __contains__(self, name): try: - getattr(self, name) - return True + val = getattr(self, name) + return val is not None except AttributeError: return False diff --git a/mongoengine/fields.py b/mongoengine/fields.py index e97aadb2..1163d51a 100644 --- a/mongoengine/fields.py +++ b/mongoengine/fields.py @@ -181,9 +181,8 @@ class ReferenceField(BaseField): if isinstance(document, (str, unicode, pymongo.objectid.ObjectId)): id_ = document else: - try: - id_ = document.id - except: + id_ = document.id + if id_ is None: raise ValidationError('You can only reference documents once ' 'they have been saved to the database') diff --git a/tests/document.py b/tests/document.py index 40dec4d6..83866207 100644 --- a/tests/document.py +++ b/tests/document.py @@ -228,7 +228,7 @@ class DocumentTest(unittest.TestCase): person_obj = collection.find_one({'name': 'Test User'}) self.assertEqual(person_obj['name'], 'Test User') self.assertEqual(person_obj['age'], 30) - self.assertEqual(person_obj['_id'], person.id) + self.assertEqual(str(person_obj['_id']), person.id) def test_delete(self): """Ensure that document may be deleted using the delete method. diff --git a/tests/fields.py b/tests/fields.py index 49c3f70f..9bad1ea1 100644 --- a/tests/fields.py +++ b/tests/fields.py @@ -46,7 +46,7 @@ class FieldTest(unittest.TestCase): name = StringField() person = Person(name='Test User') - self.assertRaises(AttributeError, getattr, person, 'id') + self.assertEqual(person.id, None) self.assertRaises(ValidationError, person.__setattr__, 'id', 47) self.assertRaises(ValidationError, person.__setattr__, 'id', 'abc') person.id = '497ce96f395f2f052a494fd4' @@ -173,8 +173,8 @@ class FieldTest(unittest.TestCase): post.author = PowerUser(name='Test User', power=47) def test_reference_validation(self): - """Ensure that invalid embedded documents cannot be assigned to - embedded document fields. + """Ensure that invalid docment objects cannot be assigned to reference + fields. """ class User(Document): name = StringField() @@ -187,10 +187,12 @@ class FieldTest(unittest.TestCase): user = User(name='Test User') + # Ensure that the referenced object must have been saved post1 = BlogPost(content='Chips and gravy taste good.') post1.author = user self.assertRaises(ValidationError, post1.save) + # Check that an invalid object type cannot be used post2 = BlogPost(content='Chips and chilli taste good.') self.assertRaises(ValidationError, post1.__setattr__, 'author', post2)