Merge branch 'master' of https://github.com/deignacio/mongoengine
This commit is contained in:
		| @@ -616,6 +616,10 @@ class DocumentMetaclass(type): | |||||||
|                     raise InvalidDocumentError("Reverse delete rules are not supported for EmbeddedDocuments (field: %s)" % field.name) |                     raise InvalidDocumentError("Reverse delete rules are not supported for EmbeddedDocuments (field: %s)" % field.name) | ||||||
|                 f.document_type.register_delete_rule(new_class, field.name, delete_rule) |                 f.document_type.register_delete_rule(new_class, field.name, delete_rule) | ||||||
|  |  | ||||||
|  |             proxy_class = getattr(field, 'proxy_class', None) | ||||||
|  |             if proxy_class is not None: | ||||||
|  |                 new_class.register_proxy_field(field.name, proxy_class) | ||||||
|  |  | ||||||
|             if field.name and hasattr(Document, field.name) and EmbeddedDocument not in new_class.mro(): |             if field.name and hasattr(Document, field.name) and EmbeddedDocument not in new_class.mro(): | ||||||
|                 raise InvalidDocumentError("%s is a document method and not a valid field name" % field.name) |                 raise InvalidDocumentError("%s is a document method and not a valid field name" % field.name) | ||||||
|  |  | ||||||
| @@ -717,6 +721,7 @@ class TopLevelDocumentMetaclass(DocumentMetaclass): | |||||||
|             'index_opts': {}, |             'index_opts': {}, | ||||||
|             'queryset_class': QuerySet, |             'queryset_class': QuerySet, | ||||||
|             'delete_rules': {}, |             'delete_rules': {}, | ||||||
|  |             'proxy_fields': {}, | ||||||
|             'allow_inheritance': True |             'allow_inheritance': True | ||||||
|         } |         } | ||||||
|  |  | ||||||
|   | |||||||
| @@ -277,6 +277,11 @@ class Document(BaseDocument): | |||||||
|         signals.pre_delete.send(self.__class__, document=self) |         signals.pre_delete.send(self.__class__, document=self) | ||||||
|  |  | ||||||
|         try: |         try: | ||||||
|  |             for field_name in self._meta['proxy_fields']: | ||||||
|  |                 proxy_class = self._meta['proxy_fields'][field_name] | ||||||
|  |                 if hasattr(proxy_class, 'delete'): | ||||||
|  |                     proxy = getattr(self, field_name) | ||||||
|  |                     proxy.delete() | ||||||
|             self.__class__.objects(pk=self.pk).delete(safe=safe) |             self.__class__.objects(pk=self.pk).delete(safe=safe) | ||||||
|         except pymongo.errors.OperationFailure, err: |         except pymongo.errors.OperationFailure, err: | ||||||
|             message = u'Could not delete document (%s)' % err.message |             message = u'Could not delete document (%s)' % err.message | ||||||
| @@ -341,6 +346,13 @@ class Document(BaseDocument): | |||||||
|         """ |         """ | ||||||
|         cls._meta['delete_rules'][(document_cls, field_name)] = rule |         cls._meta['delete_rules'][(document_cls, field_name)] = rule | ||||||
|  |  | ||||||
|  |     @classmethod | ||||||
|  |     def register_proxy_field(cls, field_name, proxy_class): | ||||||
|  |         """This method registers fields with proxy classes to delete them when | ||||||
|  |         removing this object. | ||||||
|  |         """ | ||||||
|  |         cls._meta['proxy_fields'][field_name] = proxy_class | ||||||
|  |  | ||||||
|     @classmethod |     @classmethod | ||||||
|     def drop_collection(cls): |     def drop_collection(cls): | ||||||
|         """Drops the entire collection associated with this |         """Drops the entire collection associated with this | ||||||
|   | |||||||
| @@ -1546,6 +1546,39 @@ class FieldTest(unittest.TestCase): | |||||||
|             file = FileField() |             file = FileField() | ||||||
|         DemoFile.objects.create() |         DemoFile.objects.create() | ||||||
|  |  | ||||||
|  |     def test_file_delete_cleanup(self): | ||||||
|  |         """Ensure that the gridfs file is deleted when a document | ||||||
|  |         with a GridFSProxied Field is deleted""" | ||||||
|  |         class TestFile(Document): | ||||||
|  |             file = FileField() | ||||||
|  |  | ||||||
|  |         class TestImage(Document): | ||||||
|  |             image = ImageField() | ||||||
|  |  | ||||||
|  |         TestFile.drop_collection() | ||||||
|  |  | ||||||
|  |         testfile = TestFile() | ||||||
|  |         testfile.file.put('Hello, World!') | ||||||
|  |         testfile.save() | ||||||
|  |  | ||||||
|  |         testfile_grid_id = testfile.file.grid_id | ||||||
|  |         testfile_fs = testfile.file.fs | ||||||
|  |  | ||||||
|  |         testfile.delete() | ||||||
|  |         self.assertFalse(testfile_fs.exists(testfile_grid_id)) | ||||||
|  |  | ||||||
|  |         TestImage.drop_collection() | ||||||
|  |  | ||||||
|  |         testimage = TestImage() | ||||||
|  |         testimage.image.put(open(TEST_IMAGE_PATH, 'r')) | ||||||
|  |         testimage.save() | ||||||
|  |  | ||||||
|  |         testimage_grid_id = testimage.image.grid_id | ||||||
|  |         testimage_fs = testimage.image.fs | ||||||
|  |  | ||||||
|  |         testimage.delete() | ||||||
|  |         self.assertFalse(testimage_fs.exists(testimage_grid_id)) | ||||||
|  |  | ||||||
|     def test_file_uniqueness(self): |     def test_file_uniqueness(self): | ||||||
|         """Ensure that each instance of a FileField is unique |         """Ensure that each instance of a FileField is unique | ||||||
|         """ |         """ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user