Fix bug when using GenericReferenceField, modifications to the referenced document are tracked in the parent #1934
This commit is contained in:
		| @@ -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 | ||||||
|   | |||||||
| @@ -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 | ||||||
|   | |||||||
| @@ -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): | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user