Merge pull request #2393 from bagerard/fix_listfield_change_0
Fix listfield change detection of index 0
This commit is contained in:
commit
0bbc05995a
@ -11,6 +11,8 @@ Development
|
|||||||
This should have a negative impact on performance of count see Issue #2219
|
This should have a negative impact on performance of count see Issue #2219
|
||||||
- Fix a bug that made the queryset drop the read_preference after clone().
|
- Fix a bug that made the queryset drop the read_preference after clone().
|
||||||
- Fix the behavior of Doc.objects.limit(0) which should return all documents (similar to mongodb) #2311
|
- Fix the behavior of Doc.objects.limit(0) which should return all documents (similar to mongodb) #2311
|
||||||
|
- Bug fix in ListField when updating the first item, it was saving the whole list, instead of
|
||||||
|
just replacing the first item (as it's usually done) #2392
|
||||||
|
|
||||||
Changes in 0.20.0
|
Changes in 0.20.0
|
||||||
=================
|
=================
|
||||||
|
@ -179,7 +179,7 @@ class BaseList(list):
|
|||||||
|
|
||||||
def _mark_as_changed(self, key=None):
|
def _mark_as_changed(self, key=None):
|
||||||
if hasattr(self._instance, "_mark_as_changed"):
|
if hasattr(self._instance, "_mark_as_changed"):
|
||||||
if key:
|
if key is not None:
|
||||||
self._instance._mark_as_changed(
|
self._instance._mark_as_changed(
|
||||||
"{}.{}".format(self._name, key % len(self))
|
"{}.{}".format(self._name, key % len(self))
|
||||||
)
|
)
|
||||||
|
@ -29,7 +29,8 @@ class TestDelta(MongoDBTestCase):
|
|||||||
self.delta(Document)
|
self.delta(Document)
|
||||||
self.delta(DynamicDocument)
|
self.delta(DynamicDocument)
|
||||||
|
|
||||||
def delta(self, DocClass):
|
@staticmethod
|
||||||
|
def delta(DocClass):
|
||||||
class Doc(DocClass):
|
class Doc(DocClass):
|
||||||
string_field = StringField()
|
string_field = StringField()
|
||||||
int_field = IntField()
|
int_field = IntField()
|
||||||
@ -428,13 +429,20 @@ class TestDelta(MongoDBTestCase):
|
|||||||
assert doc.dict_field == {"hello": "world"}
|
assert doc.dict_field == {"hello": "world"}
|
||||||
assert doc.list_field == ["1", 2, {"hello": "world"}]
|
assert doc.list_field == ["1", 2, {"hello": "world"}]
|
||||||
|
|
||||||
def test_delta_recursive_db_field(self):
|
def test_delta_recursive_db_field_on_doc_and_embeddeddoc(self):
|
||||||
self.delta_recursive_db_field(Document, EmbeddedDocument)
|
self.delta_recursive_db_field(Document, EmbeddedDocument)
|
||||||
|
|
||||||
|
def test_delta_recursive_db_field_on_doc_and_dynamicembeddeddoc(self):
|
||||||
self.delta_recursive_db_field(Document, DynamicEmbeddedDocument)
|
self.delta_recursive_db_field(Document, DynamicEmbeddedDocument)
|
||||||
|
|
||||||
|
def test_delta_recursive_db_field_on_dynamicdoc_and_embeddeddoc(self):
|
||||||
self.delta_recursive_db_field(DynamicDocument, EmbeddedDocument)
|
self.delta_recursive_db_field(DynamicDocument, EmbeddedDocument)
|
||||||
|
|
||||||
|
def test_delta_recursive_db_field_on_dynamicdoc_and_dynamicembeddeddoc(self):
|
||||||
self.delta_recursive_db_field(DynamicDocument, DynamicEmbeddedDocument)
|
self.delta_recursive_db_field(DynamicDocument, DynamicEmbeddedDocument)
|
||||||
|
|
||||||
def delta_recursive_db_field(self, DocClass, EmbeddedClass):
|
@staticmethod
|
||||||
|
def delta_recursive_db_field(DocClass, EmbeddedClass):
|
||||||
class Embedded(EmbeddedClass):
|
class Embedded(EmbeddedClass):
|
||||||
string_field = StringField(db_field="db_string_field")
|
string_field = StringField(db_field="db_string_field")
|
||||||
int_field = IntField(db_field="db_int_field")
|
int_field = IntField(db_field="db_int_field")
|
||||||
@ -487,6 +495,7 @@ class TestDelta(MongoDBTestCase):
|
|||||||
doc = doc.reload(10)
|
doc = doc.reload(10)
|
||||||
assert doc.embedded_field.dict_field == {}
|
assert doc.embedded_field.dict_field == {}
|
||||||
|
|
||||||
|
assert doc._get_changed_fields() == []
|
||||||
doc.embedded_field.list_field = []
|
doc.embedded_field.list_field = []
|
||||||
assert doc._get_changed_fields() == ["db_embedded_field.db_list_field"]
|
assert doc._get_changed_fields() == ["db_embedded_field.db_list_field"]
|
||||||
assert doc.embedded_field._delta() == ({}, {"db_list_field": 1})
|
assert doc.embedded_field._delta() == ({}, {"db_list_field": 1})
|
||||||
@ -634,6 +643,7 @@ class TestDelta(MongoDBTestCase):
|
|||||||
doc.save()
|
doc.save()
|
||||||
doc = doc.reload(10)
|
doc = doc.reload(10)
|
||||||
|
|
||||||
|
assert doc._delta() == ({}, {},)
|
||||||
del doc.embedded_field.list_field[2].list_field
|
del doc.embedded_field.list_field[2].list_field
|
||||||
assert doc._delta() == (
|
assert doc._delta() == (
|
||||||
{},
|
{},
|
||||||
@ -732,12 +742,12 @@ class TestDelta(MongoDBTestCase):
|
|||||||
assert organization._get_changed_fields() == []
|
assert organization._get_changed_fields() == []
|
||||||
|
|
||||||
updates, removals = organization._delta()
|
updates, removals = organization._delta()
|
||||||
assert {} == removals
|
assert removals == {}
|
||||||
assert {} == updates
|
assert updates == {}
|
||||||
|
|
||||||
organization.employees.append(person)
|
organization.employees.append(person)
|
||||||
updates, removals = organization._delta()
|
updates, removals = organization._delta()
|
||||||
assert {} == removals
|
assert removals == {}
|
||||||
assert "employees" in updates
|
assert "employees" in updates
|
||||||
|
|
||||||
def test_delta_with_dbref_false(self):
|
def test_delta_with_dbref_false(self):
|
||||||
@ -749,12 +759,12 @@ class TestDelta(MongoDBTestCase):
|
|||||||
assert organization._get_changed_fields() == []
|
assert organization._get_changed_fields() == []
|
||||||
|
|
||||||
updates, removals = organization._delta()
|
updates, removals = organization._delta()
|
||||||
assert {} == removals
|
assert removals == {}
|
||||||
assert {} == updates
|
assert updates == {}
|
||||||
|
|
||||||
organization.employees.append(person)
|
organization.employees.append(person)
|
||||||
updates, removals = organization._delta()
|
updates, removals = organization._delta()
|
||||||
assert {} == removals
|
assert removals == {}
|
||||||
assert "employees" in updates
|
assert "employees" in updates
|
||||||
|
|
||||||
def test_nested_nested_fields_mark_as_changed(self):
|
def test_nested_nested_fields_mark_as_changed(self):
|
||||||
@ -775,11 +785,11 @@ class TestDelta(MongoDBTestCase):
|
|||||||
subdoc = mydoc.subs["a"]["b"]
|
subdoc = mydoc.subs["a"]["b"]
|
||||||
subdoc.name = "bar"
|
subdoc.name = "bar"
|
||||||
|
|
||||||
assert ["name"] == subdoc._get_changed_fields()
|
assert subdoc._get_changed_fields() == ["name"]
|
||||||
assert ["subs.a.b.name"] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == ["subs.a.b.name"]
|
||||||
|
|
||||||
mydoc._clear_changed_fields()
|
mydoc._clear_changed_fields()
|
||||||
assert [] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == []
|
||||||
|
|
||||||
def test_lower_level_mark_as_changed(self):
|
def test_lower_level_mark_as_changed(self):
|
||||||
class EmbeddedDoc(EmbeddedDocument):
|
class EmbeddedDoc(EmbeddedDocument):
|
||||||
@ -794,17 +804,17 @@ class TestDelta(MongoDBTestCase):
|
|||||||
|
|
||||||
mydoc = MyDoc.objects.first()
|
mydoc = MyDoc.objects.first()
|
||||||
mydoc.subs["a"] = EmbeddedDoc()
|
mydoc.subs["a"] = EmbeddedDoc()
|
||||||
assert ["subs.a"] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == ["subs.a"]
|
||||||
|
|
||||||
subdoc = mydoc.subs["a"]
|
subdoc = mydoc.subs["a"]
|
||||||
subdoc.name = "bar"
|
subdoc.name = "bar"
|
||||||
|
|
||||||
assert ["name"] == subdoc._get_changed_fields()
|
assert subdoc._get_changed_fields() == ["name"]
|
||||||
assert ["subs.a"] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == ["subs.a"]
|
||||||
mydoc.save()
|
mydoc.save()
|
||||||
|
|
||||||
mydoc._clear_changed_fields()
|
mydoc._clear_changed_fields()
|
||||||
assert [] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == []
|
||||||
|
|
||||||
def test_upper_level_mark_as_changed(self):
|
def test_upper_level_mark_as_changed(self):
|
||||||
class EmbeddedDoc(EmbeddedDocument):
|
class EmbeddedDoc(EmbeddedDocument):
|
||||||
@ -821,15 +831,15 @@ class TestDelta(MongoDBTestCase):
|
|||||||
subdoc = mydoc.subs["a"]
|
subdoc = mydoc.subs["a"]
|
||||||
subdoc.name = "bar"
|
subdoc.name = "bar"
|
||||||
|
|
||||||
assert ["name"] == subdoc._get_changed_fields()
|
assert subdoc._get_changed_fields() == ["name"]
|
||||||
assert ["subs.a.name"] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == ["subs.a.name"]
|
||||||
|
|
||||||
mydoc.subs["a"] = EmbeddedDoc()
|
mydoc.subs["a"] = EmbeddedDoc()
|
||||||
assert ["subs.a"] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == ["subs.a"]
|
||||||
mydoc.save()
|
mydoc.save()
|
||||||
|
|
||||||
mydoc._clear_changed_fields()
|
mydoc._clear_changed_fields()
|
||||||
assert [] == mydoc._get_changed_fields()
|
assert mydoc._get_changed_fields() == []
|
||||||
|
|
||||||
def test_referenced_object_changed_attributes(self):
|
def test_referenced_object_changed_attributes(self):
|
||||||
"""Ensures that when you save a new reference to a field, the referenced object isn't altered"""
|
"""Ensures that when you save a new reference to a field, the referenced object isn't altered"""
|
||||||
|
@ -188,7 +188,7 @@ class TestDocumentInstance(MongoDBTestCase):
|
|||||||
|
|
||||||
def test_queryset_resurrects_dropped_collection(self):
|
def test_queryset_resurrects_dropped_collection(self):
|
||||||
self.Person.drop_collection()
|
self.Person.drop_collection()
|
||||||
assert [] == list(self.Person.objects())
|
assert list(self.Person.objects()) == []
|
||||||
|
|
||||||
# Ensure works correctly with inhertited classes
|
# Ensure works correctly with inhertited classes
|
||||||
class Actor(self.Person):
|
class Actor(self.Person):
|
||||||
@ -196,7 +196,7 @@ class TestDocumentInstance(MongoDBTestCase):
|
|||||||
|
|
||||||
Actor.objects()
|
Actor.objects()
|
||||||
self.Person.drop_collection()
|
self.Person.drop_collection()
|
||||||
assert [] == list(Actor.objects())
|
assert list(Actor.objects()) == []
|
||||||
|
|
||||||
def test_polymorphic_references(self):
|
def test_polymorphic_references(self):
|
||||||
"""Ensure that the correct subclasses are returned from a query
|
"""Ensure that the correct subclasses are returned from a query
|
||||||
@ -578,7 +578,8 @@ class TestDocumentInstance(MongoDBTestCase):
|
|||||||
doc.embedded_field.list_field.append(1)
|
doc.embedded_field.list_field.append(1)
|
||||||
doc.embedded_field.dict_field["woot"] = "woot"
|
doc.embedded_field.dict_field["woot"] = "woot"
|
||||||
|
|
||||||
assert doc._get_changed_fields() == [
|
changed = doc._get_changed_fields()
|
||||||
|
assert changed == [
|
||||||
"list_field",
|
"list_field",
|
||||||
"dict_field.woot",
|
"dict_field.woot",
|
||||||
"embedded_field.list_field",
|
"embedded_field.list_field",
|
||||||
|
@ -113,7 +113,7 @@ class TestDictField(MongoDBTestCase):
|
|||||||
post.info.setdefault("authors", [])
|
post.info.setdefault("authors", [])
|
||||||
post.save()
|
post.save()
|
||||||
post.reload()
|
post.reload()
|
||||||
assert [] == post.info["authors"]
|
assert post.info["authors"] == []
|
||||||
|
|
||||||
def test_dictfield_dump_document(self):
|
def test_dictfield_dump_document(self):
|
||||||
"""Ensure a DictField can handle another document's dump."""
|
"""Ensure a DictField can handle another document's dump."""
|
||||||
|
@ -1084,7 +1084,7 @@ class TestField(MongoDBTestCase):
|
|||||||
|
|
||||||
e = Simple().save()
|
e = Simple().save()
|
||||||
e.mapping = []
|
e.mapping = []
|
||||||
assert [] == e._changed_fields
|
assert e._changed_fields == []
|
||||||
|
|
||||||
class Simple(Document):
|
class Simple(Document):
|
||||||
mapping = DictField()
|
mapping = DictField()
|
||||||
@ -1093,7 +1093,7 @@ class TestField(MongoDBTestCase):
|
|||||||
|
|
||||||
e = Simple().save()
|
e = Simple().save()
|
||||||
e.mapping = {}
|
e.mapping = {}
|
||||||
assert [] == e._changed_fields
|
assert e._changed_fields == []
|
||||||
|
|
||||||
def test_slice_marks_field_as_changed(self):
|
def test_slice_marks_field_as_changed(self):
|
||||||
class Simple(Document):
|
class Simple(Document):
|
||||||
|
@ -381,7 +381,7 @@ class TestGeoField(MongoDBTestCase):
|
|||||||
|
|
||||||
meta = {"indexes": [[("location", "2dsphere"), ("datetime", 1)]]}
|
meta = {"indexes": [[("location", "2dsphere"), ("datetime", 1)]]}
|
||||||
|
|
||||||
assert [] == Log._geo_indices()
|
assert Log._geo_indices() == []
|
||||||
|
|
||||||
Log.drop_collection()
|
Log.drop_collection()
|
||||||
Log.ensure_indexes()
|
Log.ensure_indexes()
|
||||||
@ -401,7 +401,7 @@ class TestGeoField(MongoDBTestCase):
|
|||||||
"indexes": [{"fields": [("location", "2dsphere"), ("datetime", 1)]}]
|
"indexes": [{"fields": [("location", "2dsphere"), ("datetime", 1)]}]
|
||||||
}
|
}
|
||||||
|
|
||||||
assert [] == Log._geo_indices()
|
assert Log._geo_indices() == []
|
||||||
|
|
||||||
Log.drop_collection()
|
Log.drop_collection()
|
||||||
Log.ensure_indexes()
|
Log.ensure_indexes()
|
||||||
|
@ -9,10 +9,14 @@ from mongoengine.base.datastructures import BaseDict, BaseList, StrictDict
|
|||||||
class DocumentStub(object):
|
class DocumentStub(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self._changed_fields = []
|
self._changed_fields = []
|
||||||
|
self._unset_fields = []
|
||||||
|
|
||||||
def _mark_as_changed(self, key):
|
def _mark_as_changed(self, key):
|
||||||
self._changed_fields.append(key)
|
self._changed_fields.append(key)
|
||||||
|
|
||||||
|
def _mark_as_unset(self, key):
|
||||||
|
self._unset_fields.append(key)
|
||||||
|
|
||||||
|
|
||||||
class TestBaseDict:
|
class TestBaseDict:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
@ -314,7 +318,7 @@ class TestBaseList:
|
|||||||
def test___setitem___item_0_calls_mark_as_changed(self):
|
def test___setitem___item_0_calls_mark_as_changed(self):
|
||||||
base_list = self._get_baselist([True])
|
base_list = self._get_baselist([True])
|
||||||
base_list[0] = False
|
base_list[0] = False
|
||||||
assert base_list._instance._changed_fields == ["my_name"]
|
assert base_list._instance._changed_fields == ["my_name.0"]
|
||||||
assert base_list == [False]
|
assert base_list == [False]
|
||||||
|
|
||||||
def test___setitem___item_1_calls_mark_as_changed(self):
|
def test___setitem___item_1_calls_mark_as_changed(self):
|
||||||
|
Loading…
x
Reference in New Issue
Block a user