From 700bc1b4bbc5c68bbb1a117ed89168f1bb4d3ed5 Mon Sep 17 00:00:00 2001 From: Ross Lawley Date: Fri, 2 Dec 2011 08:44:15 -0800 Subject: [PATCH] Multiple fields with the same db_field now raises Exception Closes #329 --- AUTHORS | 1 + docs/changelog.rst | 1 + mongoengine/base.py | 8 +++++++- tests/document.py | 10 ++++++++++ 4 files changed, 19 insertions(+), 1 deletion(-) diff --git a/AUTHORS b/AUTHORS index 055a2b98..76f9b705 100644 --- a/AUTHORS +++ b/AUTHORS @@ -85,3 +85,4 @@ that much better: * Alexander G. Morano * jwilder * Joe Shaw + * Adam Flynn diff --git a/docs/changelog.rst b/docs/changelog.rst index 2e5f1a3e..6dd9dbc0 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -5,6 +5,7 @@ Changelog Changes in dev ============== +- Added Now raises an InvalidDocumentError when declaring multiple fields with the same db_field - Added InvalidQueryError when calling with_id with a filter - Added support for DBRefs in distinct() - Fixed issue saving False booleans diff --git a/mongoengine/base.py b/mongoengine/base.py index 67551501..c11b6278 100644 --- a/mongoengine/base.py +++ b/mongoengine/base.py @@ -492,6 +492,7 @@ class DocumentMetaclass(type): attrs['_superclasses'] = superclasses # Add the document's fields to the _fields attribute + field_names = {} for attr_name, attr_value in attrs.items(): if hasattr(attr_value, "__class__") and \ issubclass(attr_value.__class__, BaseField): @@ -499,8 +500,13 @@ class DocumentMetaclass(type): if not attr_value.db_field: attr_value.db_field = attr_name doc_fields[attr_name] = attr_value + field_names[attr_value.db_field] = field_names.get(attr_value.db_field, 0) + 1 + + duplicate_db_fields = [k for k, v in field_names.items() if v > 1] + if duplicate_db_fields: + raise InvalidDocumentError("Multiple db_fields defined for: %s " % ", ".join(duplicate_db_fields)) attrs['_fields'] = doc_fields - attrs['_db_field_map'] = dict([(k, v.db_field) for k, v in doc_fields.items() if k!=v.db_field]) + attrs['_db_field_map'] = dict([(k, v.db_field) for k, v in doc_fields.items() if k != v.db_field]) attrs['_reverse_db_field_map'] = dict([(v, k) for k, v in attrs['_db_field_map'].items()]) from mongoengine import Document, EmbeddedDocument, DictField diff --git a/tests/document.py b/tests/document.py index 78c38278..5f3bc635 100644 --- a/tests/document.py +++ b/tests/document.py @@ -2182,6 +2182,16 @@ class DocumentTest(unittest.TestCase): BlogPost.drop_collection() + def test_duplicate_db_fields_raise_invalid_document_error(self): + """Ensure a InvalidDocumentError is thrown if duplicate fields + declare the same db_field""" + + def throw_invalid_document_error(): + class Foo(Document): + name = StringField() + name2 = StringField(db_field='name') + + self.assertRaises(InvalidDocumentError, throw_invalid_document_error) def test_reverse_delete_rule_cascade_and_nullify(self): """Ensure that a referenced document is also deleted upon deletion.