Multiple fields with the same db_field now raises Exception

Closes #329
This commit is contained in:
Ross Lawley 2011-12-02 08:44:15 -08:00
parent 9bfc838029
commit 700bc1b4bb
4 changed files with 19 additions and 1 deletions

View File

@ -85,3 +85,4 @@ that much better:
* Alexander G. Morano * Alexander G. Morano
* jwilder * jwilder
* Joe Shaw * Joe Shaw
* Adam Flynn

View File

@ -5,6 +5,7 @@ Changelog
Changes in dev 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 InvalidQueryError when calling with_id with a filter
- Added support for DBRefs in distinct() - Added support for DBRefs in distinct()
- Fixed issue saving False booleans - Fixed issue saving False booleans

View File

@ -492,6 +492,7 @@ class DocumentMetaclass(type):
attrs['_superclasses'] = superclasses attrs['_superclasses'] = superclasses
# Add the document's fields to the _fields attribute # Add the document's fields to the _fields attribute
field_names = {}
for attr_name, attr_value in attrs.items(): for attr_name, attr_value in attrs.items():
if hasattr(attr_value, "__class__") and \ if hasattr(attr_value, "__class__") and \
issubclass(attr_value.__class__, BaseField): issubclass(attr_value.__class__, BaseField):
@ -499,8 +500,13 @@ class DocumentMetaclass(type):
if not attr_value.db_field: if not attr_value.db_field:
attr_value.db_field = attr_name attr_value.db_field = attr_name
doc_fields[attr_name] = attr_value 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['_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()]) attrs['_reverse_db_field_map'] = dict([(v, k) for k, v in attrs['_db_field_map'].items()])
from mongoengine import Document, EmbeddedDocument, DictField from mongoengine import Document, EmbeddedDocument, DictField

View File

@ -2182,6 +2182,16 @@ class DocumentTest(unittest.TestCase):
BlogPost.drop_collection() 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): def test_reverse_delete_rule_cascade_and_nullify(self):
"""Ensure that a referenced document is also deleted upon deletion. """Ensure that a referenced document is also deleted upon deletion.