From bc53dd68308c88cc41bb3fb183c1d41392b40968 Mon Sep 17 00:00:00 2001 From: Matthew Ellison Date: Wed, 19 Nov 2014 15:50:32 -0500 Subject: [PATCH] Generate Unique Indices for Lists of EmbeddedDocs - Unique indices are now created in the database for EmbeddedDocument fields when the EmbeddedDocument is in a ListField - Closes Issue #358 --- AUTHORS | 1 + mongoengine/base/document.py | 3 +++ tests/document/indexes.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/AUTHORS b/AUTHORS index d377d177..fb9a1ce5 100644 --- a/AUTHORS +++ b/AUTHORS @@ -215,3 +215,4 @@ that much better: * André Ericson https://github.com/aericson) * Mikhail Moshnogorsky (https://github.com/mikhailmoshnogorsky) * Diego Berrocal (https://github.com/cestdiego) + * Matthew Ellison (https://github.com/mmelliso) diff --git a/mongoengine/base/document.py b/mongoengine/base/document.py index 854ed6b4..7a013021 100644 --- a/mongoengine/base/document.py +++ b/mongoengine/base/document.py @@ -816,6 +816,9 @@ class BaseDocument(object): index = {'fields': fields, 'unique': True, 'sparse': sparse} unique_indexes.append(index) + if field.__class__.__name__ == "ListField": + field = field.field + # Grab any embedded document field unique indexes if (field.__class__.__name__ == "EmbeddedDocumentField" and field.document_type != cls): diff --git a/tests/document/indexes.py b/tests/document/indexes.py index 4103c7ae..4815350f 100644 --- a/tests/document/indexes.py +++ b/tests/document/indexes.py @@ -577,6 +577,38 @@ class IndexesTest(unittest.TestCase): BlogPost.drop_collection() + def test_unique_embedded_document_in_list(self): + """ + Ensure that the uniqueness constraints are applied to fields in + embedded documents, even when the embedded documents in in a + list field. + """ + class SubDocument(EmbeddedDocument): + year = IntField(db_field='yr') + slug = StringField(unique=True) + + class BlogPost(Document): + title = StringField() + subs = ListField(EmbeddedDocumentField(SubDocument)) + + BlogPost.drop_collection() + + post1 = BlogPost( + title='test1', subs=[ + SubDocument(year=2009, slug='conflict'), + SubDocument(year=2009, slug='conflict') + ] + ) + post1.save() + + post2 = BlogPost( + title='test2', subs=[SubDocument(year=2014, slug='conflict')] + ) + + self.assertRaises(NotUniqueError, post2.save) + + BlogPost.drop_collection() + def test_unique_with_embedded_document_and_embedded_unique(self): """Ensure that uniqueness constraints are applied to fields on embedded documents. And work with unique_with as well.