Skip to content

Commit 9f9cd0a

Browse files
committed
support .where() with modify (previously silently ignored)
1 parent e77daa6 commit 9f9cd0a

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

docs/changelog.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Development
2222
- Add support for collation/hint/comment to delete/update and aggregate #2842
2323
- BREAKING CHANGE: Remove LongField as it's equivalent to IntField since we drop support to Python2 long time ago (User should simply switch to IntField) #2309
2424
- BugFix - Calling .clear on a ListField wasn't being marked as changed (and flushed to db upon .save()) #2858
25-
25+
- BugFix - Take `where()` into account when using `.modify()`, as in MyDocument.objects().where("this[field] >= this[otherfield]").modify(field='new') #2044
2626

2727
Changes in 0.29.0
2828
=================

mongoengine/queryset/base.py

+5
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,11 @@ def modify(
727727

728728
queryset = self.clone()
729729
query = queryset._query
730+
731+
if self._where_clause:
732+
where_clause = self._sub_js_fields(self._where_clause)
733+
query["$where"] = where_clause
734+
730735
if not remove:
731736
update = transform.update(queryset._document, **update)
732737
sort = queryset._ordering

tests/queryset/test_queryset.py

+56-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
from mongoengine.queryset.base import BaseQuerySet
2929
from tests.utils import (
3030
db_ops_tracker,
31+
get_as_pymongo,
3132
requires_mongodb_gte_42,
3233
requires_mongodb_gte_44,
3334
requires_mongodb_lt_42,
@@ -4456,7 +4457,7 @@ class Comment(Document):
44564457
]
44574458
assert ([("_cls", 1), ("message", 1)], False, False) in info
44584459

4459-
def test_where(self):
4460+
def test_where_query(self):
44604461
"""Ensure that where clauses work."""
44614462

44624463
class IntPair(Document):
@@ -4499,6 +4500,60 @@ class IntPair(Document):
44994500
with pytest.raises(TypeError):
45004501
list(IntPair.objects.where(fielda__gte=3))
45014502

4503+
def test_where_query_field_name_subs(self):
4504+
class DomainObj(Document):
4505+
field_1 = StringField(db_field="field_2")
4506+
4507+
DomainObj.drop_collection()
4508+
4509+
DomainObj(field_1="test").save()
4510+
4511+
obj = DomainObj.objects.where("this[~field_1] == 'NOTMATCHING'")
4512+
assert not list(obj)
4513+
4514+
obj = DomainObj.objects.where("this[~field_1] == 'test'")
4515+
assert list(obj)
4516+
4517+
def test_where_modify(self):
4518+
class DomainObj(Document):
4519+
field = StringField()
4520+
4521+
DomainObj.drop_collection()
4522+
4523+
DomainObj(field="test").save()
4524+
4525+
obj = DomainObj.objects.where("this[~field] == 'NOTMATCHING'")
4526+
assert not list(obj)
4527+
4528+
obj = DomainObj.objects.where("this[~field] == 'test'")
4529+
assert list(obj)
4530+
4531+
qs = DomainObj.objects.where("this[~field] == 'NOTMATCHING'").modify(
4532+
field="new"
4533+
)
4534+
assert not qs
4535+
4536+
qs = DomainObj.objects.where("this[~field] == 'test'").modify(field="new")
4537+
assert qs
4538+
4539+
def test_where_modify_field_name_subs(self):
4540+
class DomainObj(Document):
4541+
field_1 = StringField(db_field="field_2")
4542+
4543+
DomainObj.drop_collection()
4544+
4545+
DomainObj(field_1="test").save()
4546+
4547+
obj = DomainObj.objects.where("this[~field_1] == 'NOTMATCHING'").modify(
4548+
field_1="new"
4549+
)
4550+
assert not obj
4551+
4552+
obj = DomainObj.objects.where("this[~field_1] == 'test'").modify(field_1="new")
4553+
assert obj
4554+
4555+
assert get_as_pymongo(obj) == {"_id": obj.id, "field_2": "new"}
4556+
45024557
def test_scalar(self):
45034558
class Organization(Document):
45044559
name = StringField()

0 commit comments

Comments
 (0)