Merge pull request #2182 from daewok/fix-embedded-document-equality-with-lazy-refs

Fix EmbeddedDocument equality with LazyReferenceFields
This commit is contained in:
Bastien Gérard 2019-12-16 23:57:50 +01:00 committed by GitHub
commit 8d31f165c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 42 additions and 0 deletions

View File

@ -253,3 +253,4 @@ that much better:
* Gaurav Dadhania (https://github.com/GVRV) * Gaurav Dadhania (https://github.com/GVRV)
* Yurii Andrieiev (https://github.com/yandrieiev) * Yurii Andrieiev (https://github.com/yandrieiev)
* Filip Kucharczyk (https://github.com/Pacu2) * Filip Kucharczyk (https://github.com/Pacu2)
* Eric Timmons (https://github.com/daewok)

View File

@ -17,6 +17,7 @@ Development
- If you catch/use ``MongoEngineConnectionError`` in your code, you'll have to rename it. - If you catch/use ``MongoEngineConnectionError`` in your code, you'll have to rename it.
- BREAKING CHANGE: Positional arguments when instantiating a document are no longer supported. #2103 - BREAKING CHANGE: Positional arguments when instantiating a document are no longer supported. #2103
- From now on keyword arguments (e.g. ``Doc(field_name=value)``) are required. - From now on keyword arguments (e.g. ``Doc(field_name=value)``) are required.
- BREAKING CHANGE: A ``LazyReferenceField`` is now stored in the ``_data`` field of its parent as a ``DBRef``, ``Document``, or ``EmbeddedDocument`` (``ObjectId`` is no longer allowed). #2182
- DEPRECATION: ``Q.empty`` & ``QNode.empty`` are marked as deprecated and will be removed in a next version of MongoEngine. #2210 - DEPRECATION: ``Q.empty`` & ``QNode.empty`` are marked as deprecated and will be removed in a next version of MongoEngine. #2210
- Added ability to check if Q or QNode are empty by parsing them to bool. - Added ability to check if Q or QNode are empty by parsing them to bool.
- Instead of ``Q(name="John").empty`` use ``not Q(name="John")``. - Instead of ``Q(name="John").empty`` use ``not Q(name="John")``.

View File

@ -2502,6 +2502,13 @@ class LazyReferenceField(BaseField):
else: else:
return pk return pk
def to_python(self, value):
"""Convert a MongoDB-compatible type to a Python type."""
if not isinstance(value, (DBRef, Document, EmbeddedDocument)):
collection = self.document_type._get_collection_name()
value = DBRef(collection, self.document_type.id.to_python(value))
return value
def validate(self, value): def validate(self, value):
if isinstance(value, LazyReference): if isinstance(value, LazyReference):
if value.collection != self.document_type._get_collection_name(): if value.collection != self.document_type._get_collection_name():

View File

@ -3319,6 +3319,39 @@ class TestInstance(MongoDBTestCase):
f1.ref # Dereferences lazily f1.ref # Dereferences lazily
assert f1 == f2 assert f1 == f2
def test_embedded_document_equality_with_lazy_ref(self):
class Job(EmbeddedDocument):
boss = LazyReferenceField("Person")
boss_dbref = LazyReferenceField("Person", dbref=True)
class Person(Document):
job = EmbeddedDocumentField(Job)
Person.drop_collection()
boss = Person()
worker = Person(job=Job(boss=boss, boss_dbref=boss))
boss.save()
worker.save()
worker1 = Person.objects.get(id=worker.id)
# worker1.job should be equal to the job used originally to create the
# document.
self.assertEqual(worker1.job, worker.job)
# worker1.job should be equal to a newly created Job EmbeddedDocument
# using either the Boss object or his ID.
self.assertEqual(worker1.job, Job(boss=boss, boss_dbref=boss))
self.assertEqual(worker1.job, Job(boss=boss.id, boss_dbref=boss.id))
# The above equalities should also hold after worker1.job.boss has been
# fetch()ed.
worker1.job.boss.fetch()
self.assertEqual(worker1.job, worker.job)
self.assertEqual(worker1.job, Job(boss=boss, boss_dbref=boss))
self.assertEqual(worker1.job, Job(boss=boss.id, boss_dbref=boss.id))
def test_dbref_equality(self): def test_dbref_equality(self):
class Test2(Document): class Test2(Document):
name = StringField() name = StringField()