From 8766768f6f922a0c9808769b8aa525565c06e8b5 Mon Sep 17 00:00:00 2001 From: Ollie Ford Date: Fri, 5 Aug 2016 00:11:02 +0100 Subject: [PATCH 1/2] adds test for falsey primary_key behaviour This commit adds a test for the incorrect behaviour raised in #1352, in which updating a document with a `0` primary_key fails with: > OperationError: attempt to update a document not yet saved despite prior saving. The issue is almost certainly due to a failure to distinguish between `None` and other falsey values. --- tests/document/instance.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/tests/document/instance.py b/tests/document/instance.py index cb2c17462..1342f981c 100644 --- a/tests/document/instance.py +++ b/tests/document/instance.py @@ -3202,5 +3202,20 @@ class A(Document): self.assertEqual(b._instance, a) self.assertEqual(idx, 2) + def test_falsey_pk(self): + """Ensure that we can create and update a document with Falsey PK. + """ + class Person(Document): + age = IntField(primary_key=True) + height = FloatField() + + person = Person() + person.age = 0 + person.height = 1.89 + person.save() + + person.update(set__height=2.0) + + if __name__ == '__main__': unittest.main() From cb1c9c37f982865470ff428f437a44278e17a96a Mon Sep 17 00:00:00 2001 From: Ollie Ford Date: Fri, 5 Aug 2016 00:20:08 +0100 Subject: [PATCH 2/2] fixes support for falsey primary_keys Closes #1352; in which updates to such a document would raise an exception as though it had never been saved. --- mongoengine/document.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/mongoengine/document.py b/mongoengine/document.py index 607b1bd99..91dcafc47 100644 --- a/mongoengine/document.py +++ b/mongoengine/document.py @@ -472,7 +472,7 @@ def update(self, **kwargs): Raises :class:`OperationError` if called on an object that has not yet been saved. """ - if not self.pk: + if self.pk is None: if kwargs.get('upsert', False): query = self.to_mongo() if "_cls" in query: @@ -604,7 +604,7 @@ def reload(self, *fields, **kwargs): elif "max_depth" in kwargs: max_depth = kwargs["max_depth"] - if not self.pk: + if self.pk is None: raise self.DoesNotExist("Document does not exist") obj = self._qs.read_preference(ReadPreference.PRIMARY).filter( **self._object_key).only(*fields).limit( @@ -655,7 +655,7 @@ def _reload(self, key, value): def to_dbref(self): """Returns an instance of :class:`~bson.dbref.DBRef` useful in `__raw__` queries.""" - if not self.pk: + if self.pk is None: msg = "Only saved documents can have a valid dbref" raise OperationError(msg) return DBRef(self.__class__._get_collection_name(), self.pk)