diff --git a/docs/changelog.rst b/docs/changelog.rst index e0f497cd..9c91f13c 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -2,6 +2,10 @@ Changelog ========= +Changes in 0.6.14 +================= +- Added support for add_to_set and each + Changes in 0.6.13 ================ - Fixed EmbeddedDocument db_field validation issue diff --git a/mongoengine/queryset.py b/mongoengine/queryset.py index 21e3f9e5..d795ec1f 100644 --- a/mongoengine/queryset.py +++ b/mongoengine/queryset.py @@ -1387,11 +1387,16 @@ class QuerySet(object): # Convert value to proper value field = cleaned_fields[-1] - if op in (None, 'set', 'push', 'pull', 'addToSet'): + if op in (None, 'set', 'push', 'pull'): if field.required or value is not None: value = field.prepare_query_value(op, value) elif op in ('pushAll', 'pullAll'): value = [field.prepare_query_value(op, v) for v in value] + elif op == 'addToSet': + if isinstance(value, (list, tuple, set)): + value = [field.prepare_query_value(op, v) for v in value] + elif field.required or value is not None: + value = field.prepare_query_value(op, value) key = '.'.join(parts) @@ -1407,6 +1412,8 @@ class QuerySet(object): parts.reverse() for key in parts: value = {key: value} + elif op == 'addToSet' and isinstance(value, list): + value = {key: {"$each": value}} else: value = {key: value} key = '$' + op diff --git a/setup.cfg b/setup.cfg index 43097a49..083306a6 100644 --- a/setup.cfg +++ b/setup.cfg @@ -10,4 +10,4 @@ cover-html-dir = ../htmlcov cover-package = mongoengine cover-erase = 1 where = tests -#tests = test_bugfix.py +tests = test_bugfix.py diff --git a/tests/test_queryset.py b/tests/test_queryset.py index e7ee6780..939451c1 100644 --- a/tests/test_queryset.py +++ b/tests/test_queryset.py @@ -1520,7 +1520,7 @@ class QuerySetTest(unittest.TestCase): BlogPost.drop_collection() - def test_update_push_and_pull(self): + def test_update_push_and_pull_add_to_set(self): """Ensure that the 'pull' update operation works correctly. """ class BlogPost(Document): @@ -1553,6 +1553,23 @@ class QuerySetTest(unittest.TestCase): post.reload() self.assertEqual(post.tags, ["code", "mongodb"]) + def test_add_to_set_each(self): + class Item(Document): + name = StringField(required=True) + description = StringField(max_length=50) + parents = ListField(ReferenceField('self')) + + Item.drop_collection() + + item = Item(name='test item').save() + parent_1 = Item(name='parent 1').save() + parent_2 = Item(name='parent 2').save() + + item.update(add_to_set__parents=[parent_1, parent_2, parent_1]) + item.reload() + + self.assertEqual([parent_1, parent_2], item.parents) + def test_pull_nested(self): class User(Document):