Make python value for LazyReferenceFields be a DBRef

Previously, when reading a LazyReferenceField from the DB, it was stored
internally in the parent document's _data field as an ObjectId. However, this
meant that equality tests using an enclosing EmbeddedDocument would not return
True when the EmbeddedDocument being compared to contained a DBRef or Document
in _data. Enclosing Documents were largely unaffected because they look at the
primary key for equality (which EmbeddedDocuments lack).

This makes the internal Python representation of a LazyReferenceField (before
the LazyReference itself has been constructed) a DBRef, using code identical to
ReferenceField.
This commit is contained in:
Eric Timmons 2019-10-16 09:50:47 -04:00
parent 50882e5bb0
commit dc7b96a569
2 changed files with 10 additions and 1 deletions

View File

@ -2502,6 +2502,15 @@ 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 self.dbref and 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

@ -3321,7 +3321,7 @@ class TestInstance(MongoDBTestCase):
def test_embedded_document_equality_with_lazy_ref(self): def test_embedded_document_equality_with_lazy_ref(self):
class Job(EmbeddedDocument): class Job(EmbeddedDocument):
boss = LazyReferenceField('Person') boss = LazyReferenceField("Person")
class Person(Document): class Person(Document):
job = EmbeddedDocumentField(Job) job = EmbeddedDocumentField(Job)