Fix bug when using GenericReferenceField, modifications to the referenced document are tracked in the parent #1934

This commit is contained in:
Bastien Gérard 2018-10-30 22:52:50 +01:00
parent 18b47e4a73
commit f6cd349a16
3 changed files with 33 additions and 4 deletions

View File

@ -6,6 +6,8 @@ Development
=========== ===========
- QuerySet limit function behaviour: Passing 0 as parameter will return all the documents in the cursor #1611 - QuerySet limit function behaviour: Passing 0 as parameter will return all the documents in the cursor #1611
- bulk insert updates the ids of the input documents #1919 - bulk insert updates the ids of the input documents #1919
- Fix an harmless bug related to GenericReferenceField where modifications in the generic-referenced document
were tracked in the parent (#1934)
- (Fill this out as you fix issues and develop your features). - (Fill this out as you fix issues and develop your features).
======= =======
Changes in 0.15.4 Changes in 0.15.4

View File

@ -528,6 +528,7 @@ class BaseDocument(object):
EmbeddedDocument = _import_class('EmbeddedDocument') EmbeddedDocument = _import_class('EmbeddedDocument')
DynamicEmbeddedDocument = _import_class('DynamicEmbeddedDocument') DynamicEmbeddedDocument = _import_class('DynamicEmbeddedDocument')
ReferenceField = _import_class('ReferenceField') ReferenceField = _import_class('ReferenceField')
GenericReferenceField = _import_class('GenericReferenceField')
SortedListField = _import_class('SortedListField') SortedListField = _import_class('SortedListField')
changed_fields = [] changed_fields = []
@ -560,7 +561,7 @@ class BaseDocument(object):
elif (isinstance(data, (list, tuple, dict)) and elif (isinstance(data, (list, tuple, dict)) and
db_field_name not in changed_fields): db_field_name not in changed_fields):
if (hasattr(field, 'field') and if (hasattr(field, 'field') and
isinstance(field.field, ReferenceField)): isinstance(field.field, (ReferenceField, GenericReferenceField))):
continue continue
elif isinstance(field, SortedListField) and field._ordering: elif isinstance(field, SortedListField) and field._ordering:
# if ordering is affected whole list is changed # if ordering is affected whole list is changed

View File

@ -2816,7 +2816,32 @@ class FieldTest(MongoDBTestCase):
doc = Doc.objects.get(ref=DBRef('doc', doc1.pk)) doc = Doc.objects.get(ref=DBRef('doc', doc1.pk))
self.assertEqual(doc, doc2) self.assertEqual(doc, doc2)
def test_generic_reference_filter_by_objectid(self): def test_generic_reference_is_not_tracked_in_parent_doc(self):
"""Ensure that modifications of related documents (through generic reference) don't influence
the owner changed fields (#1934)
"""
class Doc1(Document):
name = StringField()
class Doc2(Document):
ref = GenericReferenceField()
refs = ListField(GenericReferenceField())
Doc1.drop_collection()
Doc2.drop_collection()
doc1 = Doc1(name='garbage1').save()
doc11 = Doc1(name='garbage11').save()
doc2 = Doc2(ref=doc1, refs=[doc11]).save()
doc2.ref.name = 'garbage2'
self.assertEqual(doc2._get_changed_fields(), [])
doc2.refs[0].name = 'garbage3'
self.assertEqual(doc2._get_changed_fields(), [])
self.assertEqual(doc2._delta(), ({}, {}))
def test_generic_reference_field(self):
"""Ensure we can search for a specific generic reference by """Ensure we can search for a specific generic reference by
providing its DBRef. providing its DBRef.
""" """
@ -4348,6 +4373,7 @@ class TestEmbeddedDocumentField(MongoDBTestCase):
class MyFailingdoc2(Document): class MyFailingdoc2(Document):
emb = EmbeddedDocumentField('MyDoc') emb = EmbeddedDocumentField('MyDoc')
class CachedReferenceFieldTest(MongoDBTestCase): class CachedReferenceFieldTest(MongoDBTestCase):
def test_cached_reference_field_get_and_save(self): def test_cached_reference_field_get_and_save(self):