nar*_*eso 84 django storage file django-models imagefield
我使用1.2.5标准ImageField并使用内置存储后端.文件上传很好但是当我从管理员删除条目时,服务器上的实际文件不会删除.
dar*_*inm 97
您可以接收pre_delete
或发post_delete
信号(请参阅下面的@ toto_tico注释)并在FileField对象上调用delete方法,因此(在models.py中):
class MyModel(models.Model):
file = models.FileField()
...
# Receive the pre_delete signal and delete the file associated with the model instance.
from django.db.models.signals import pre_delete
from django.dispatch.dispatcher import receiver
@receiver(pre_delete, sender=MyModel)
def mymodel_delete(sender, instance, **kwargs):
# Pass false so FileField doesn't save the model.
instance.file.delete(False)
Run Code Online (Sandbox Code Playgroud)
un1*_*n1t 44
pip install django-cleanup
Run Code Online (Sandbox Code Playgroud)
settings.py
INSTALLED_APPS = (
...
'django_cleanup', # should go after your apps
)
Run Code Online (Sandbox Code Playgroud)
Kus*_*hal 34
Django 1.5解决方案:我使用post_delete的原因是我的应用程序内部的各种原因.
from django.db.models.signals import post_delete
from django.dispatch import receiver
@receiver(post_delete, sender=Photo)
def photo_post_delete_handler(sender, **kwargs):
photo = kwargs['instance']
storage, path = photo.original_image.storage, photo.original_image.path
storage.delete(path)
Run Code Online (Sandbox Code Playgroud)
我把它放在models.py文件的底部.
该original_image
领域是ImageField
我的Photo
模型.
Dav*_*lli 17
此代码在Django 1.4上运行良好,也可以在Admin面板上运行.
class ImageModel(models.Model):
image = ImageField(...)
def delete(self, *args, **kwargs):
# You have to prepare what you need before delete the model
storage, path = self.image.storage, self.image.path
# Delete the model before the file
super(ImageModel, self).delete(*args, **kwargs)
# Delete the file after the model
storage.delete(path)
Run Code Online (Sandbox Code Playgroud)
在删除模型之前获取存储和路径很重要,否则后者在删除时也会保持无效.
您需要删除同时在实际的文件delete
和update
.
from django.db import models
class MyImageModel(models.Model):
image = models.ImageField(upload_to='images')
def remove_on_image_update(self):
try:
# is the object in the database yet?
obj = MyImageModel.objects.get(id=self.id)
except MyImageModel.DoesNotExist:
# object is not in db, nothing to worry about
return
# is the save due to an update of the actual image file?
if obj.image and self.image and obj.image != self.image:
# delete the old image file from the storage in favor of the new file
obj.image.delete()
def delete(self, *args, **kwargs):
# object is being removed from db, remove the file from storage first
self.image.delete()
return super(MyImageModel, self).delete(*args, **kwargs)
def save(self, *args, **kwargs):
# object is possibly being updated, if so, clean up.
self.remove_on_image_update()
return super(MyImageModel, self).save(*args, **kwargs)
Run Code Online (Sandbox Code Playgroud)
您可以考虑使用pre_delete或post_delete信号:
https://docs.djangoproject.com/en/dev/topics/signals/
当然,删除FileField自动删除的相同原因也适用于此处.如果删除在其他地方引用的文件,则会出现问题.
在我的情况下,这似乎是合适的,因为我有一个专用的文件模型来管理我的所有文件.
注意:由于某种原因,post_delete似乎无法正常工作.该文件被删除,但数据库记录仍然存在,这与我的预期完全相反,即使在错误条件下也是如此.pre_delete工作得很好.