From b392e3102e94657fd663ba4e2b188ec648fe1c1b Mon Sep 17 00:00:00 2001 From: Agustin Barto Date: Fri, 17 May 2019 13:41:02 -0300 Subject: [PATCH 1/3] Add support to transform. Add pull tests for and . --- mongoengine/queryset/transform.py | 2 +- tests/queryset/transform.py | 15 ++++++++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/mongoengine/queryset/transform.py b/mongoengine/queryset/transform.py index 3de10a69..7241efbd 100644 --- a/mongoengine/queryset/transform.py +++ b/mongoengine/queryset/transform.py @@ -281,7 +281,7 @@ def update(_doc_cls=None, **update): if op == 'pull': if field.required or value is not None: - if match == 'in' and not isinstance(value, dict): + if match in ('in', 'nin') and not isinstance(value, dict): value = _prepare_query_for_iterable(field, op, value) else: value = field.prepare_query_value(op, value) diff --git a/tests/queryset/transform.py b/tests/queryset/transform.py index 8064f09c..3c7c945f 100644 --- a/tests/queryset/transform.py +++ b/tests/queryset/transform.py @@ -276,13 +276,18 @@ class TransformTest(unittest.TestCase): title = StringField() content = EmbeddedDocumentField(SubDoc) - word = Word(word='abc', index=1) - update = transform.update(MainDoc, pull__content__text=word) - self.assertEqual(update, {'$pull': {'content.text': SON([('word', u'abc'), ('index', 1)])}}) + # word = Word(word='abc', index=1) + # update = transform.update(MainDoc, pull__content__text=word) + # self.assertEqual(update, {'$pull': {'content.text': SON([('word', u'abc'), ('index', 1)])}}) - update = transform.update(MainDoc, pull__content__heading='xyz') - self.assertEqual(update, {'$pull': {'content.heading': 'xyz'}}) + # update = transform.update(MainDoc, pull__content__heading='xyz') + # self.assertEqual(update, {'$pull': {'content.heading': 'xyz'}}) + # update = transform.update(MainDoc, pull__content__text__word__in=['foo', 'bar']) + # self.assertEqual(update, {'$pull': {'content.text': {'word': {'$in': ['foo', 'bar']}}}}) + + update = transform.update(MainDoc, pull__content__text__word__nin=['foo', 'bar']) + self.assertEqual(update, {'$pull': {'content.text': {'word': {'$nin': ['foo', 'bar']}}}}) if __name__ == '__main__': unittest.main() From 2b17985a11b5ff9baa206d513f2d05e502122039 Mon Sep 17 00:00:00 2001 From: Agustin Barto Date: Fri, 17 May 2019 13:55:00 -0300 Subject: [PATCH 2/3] Uncomment tests. --- tests/queryset/transform.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/tests/queryset/transform.py b/tests/queryset/transform.py index 3c7c945f..b2bc1d6c 100644 --- a/tests/queryset/transform.py +++ b/tests/queryset/transform.py @@ -276,15 +276,15 @@ class TransformTest(unittest.TestCase): title = StringField() content = EmbeddedDocumentField(SubDoc) - # word = Word(word='abc', index=1) - # update = transform.update(MainDoc, pull__content__text=word) - # self.assertEqual(update, {'$pull': {'content.text': SON([('word', u'abc'), ('index', 1)])}}) + word = Word(word='abc', index=1) + update = transform.update(MainDoc, pull__content__text=word) + self.assertEqual(update, {'$pull': {'content.text': SON([('word', u'abc'), ('index', 1)])}}) - # update = transform.update(MainDoc, pull__content__heading='xyz') - # self.assertEqual(update, {'$pull': {'content.heading': 'xyz'}}) + update = transform.update(MainDoc, pull__content__heading='xyz') + self.assertEqual(update, {'$pull': {'content.heading': 'xyz'}}) - # update = transform.update(MainDoc, pull__content__text__word__in=['foo', 'bar']) - # self.assertEqual(update, {'$pull': {'content.text': {'word': {'$in': ['foo', 'bar']}}}}) + update = transform.update(MainDoc, pull__content__text__word__in=['foo', 'bar']) + self.assertEqual(update, {'$pull': {'content.text': {'word': {'$in': ['foo', 'bar']}}}}) update = transform.update(MainDoc, pull__content__text__word__nin=['foo', 'bar']) self.assertEqual(update, {'$pull': {'content.text': {'word': {'$nin': ['foo', 'bar']}}}}) From 6b9d71554e397645071eacfe0b4f1fce7f834e46 Mon Sep 17 00:00:00 2001 From: Agustin Barto Date: Fri, 17 May 2019 17:23:52 -0300 Subject: [PATCH 3/3] Add integration tests --- tests/queryset/queryset.py | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/tests/queryset/queryset.py b/tests/queryset/queryset.py index 31b1641e..0b88193e 100644 --- a/tests/queryset/queryset.py +++ b/tests/queryset/queryset.py @@ -2193,6 +2193,40 @@ class QuerySetTest(unittest.TestCase): Site.objects(id=s.id).update_one( pull_all__collaborators__helpful__name=['Ross']) + def test_pull_from_nested_embedded_using_in_nin(self): + """Ensure that the 'pull' update operation works on embedded documents using 'in' and 'nin' operators. + """ + + class User(EmbeddedDocument): + name = StringField() + + def __unicode__(self): + return '%s' % self.name + + class Collaborator(EmbeddedDocument): + helpful = ListField(EmbeddedDocumentField(User)) + unhelpful = ListField(EmbeddedDocumentField(User)) + + class Site(Document): + name = StringField(max_length=75, unique=True, required=True) + collaborators = EmbeddedDocumentField(Collaborator) + + Site.drop_collection() + + a = User(name='Esteban') + b = User(name='Frank') + x = User(name='Harry') + y = User(name='John') + + s = Site(name="test", collaborators=Collaborator( + helpful=[a, b], unhelpful=[x, y])).save() + + Site.objects(id=s.id).update_one(pull__collaborators__helpful__name__in=['Esteban']) # Pull a + self.assertEqual(Site.objects.first().collaborators['helpful'], [b]) + + Site.objects(id=s.id).update_one(pull__collaborators__unhelpful__name__nin=['John']) # Pull x + self.assertEqual(Site.objects.first().collaborators['unhelpful'], [y]) + def test_pull_from_nested_mapfield(self): class Collaborator(EmbeddedDocument):