diff --git a/AUTHORS b/AUTHORS index b38825dca..5998520a2 100644 --- a/AUTHORS +++ b/AUTHORS @@ -247,3 +247,4 @@ that much better: * Erdenezul Batmunkh (https://github.com/erdenezul) * Andy Yankovsky (https://github.com/werat) * Bastien GĂ©rard (https://github.com/bagerard) + * Trevor Hall (https://github.com/tjhall13) diff --git a/docs/changelog.rst b/docs/changelog.rst index d9742d6fa..30b881650 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -6,6 +6,11 @@ Development =========== - (Fill this out as you fix issues and develop your features). +================= +Changes in 0.16.3 +================= +- Fix $push with $position operator not working with lists in embedded document #1965 + ================= Changes in 0.16.2 ================= diff --git a/mongoengine/queryset/transform.py b/mongoengine/queryset/transform.py index 41f99bbce..2d22c3507 100644 --- a/mongoengine/queryset/transform.py +++ b/mongoengine/queryset/transform.py @@ -345,7 +345,7 @@ def update(_doc_cls=None, **update): value = {key: {'$each': value}} elif op in ('push', 'pushAll'): if parts[-1].isdigit(): - key = parts[0] + key = '.'.join(parts[0:-1]) position = int(parts[-1]) # $position expects an iterable. If pushing a single value, # wrap it in a list. diff --git a/tests/document/instance.py b/tests/document/instance.py index ad22c0863..5319ace41 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -842,10 +842,16 @@ def test_modify_update(self): @requires_mongodb_gte_26 def test_modify_with_positional_push(self): + class Content(EmbeddedDocument): + keywords = ListField(StringField()) + class BlogPost(Document): tags = ListField(StringField()) + content = EmbeddedDocumentField(Content) + + post = BlogPost.objects.create( + tags=['python'], content=Content(keywords=['ipsum'])) - post = BlogPost.objects.create(tags=['python']) self.assertEqual(post.tags, ['python']) post.modify(push__tags__0=['code', 'mongo']) self.assertEqual(post.tags, ['code', 'mongo', 'python']) @@ -856,6 +862,16 @@ class BlogPost(Document): ['code', 'mongo', 'python'] ) + self.assertEqual(post.content.keywords, ['ipsum']) + post.modify(push__content__keywords__0=['lorem']) + self.assertEqual(post.content.keywords, ['lorem', 'ipsum']) + + # Assert same order of the list items is maintained in the db + self.assertEqual( + BlogPost._get_collection().find_one({'_id': post.pk})['content']['keywords'], + ['lorem', 'ipsum'] + ) + def test_save(self): """Ensure that a document may be saved in the database."""