표준 ImageField와 함께 1.2.5를 사용하고 내장 스토리지 백엔드를 사용하고 있습니다. 파일은 잘 업로드되지만 관리자에서 항목을 제거하면 서버의 실제 파일이 삭제되지 않습니다.
답변
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)
답변
pip install django-cleanup
settings.py
INSTALLED_APPS = (
...
'django_cleanup', # should go after your apps
)
답변
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)
나는 이것을 models.py 파일 하단에 붙였다.
original_image
필드입니다 ImageField
내에서 Photo
모델.
답변
이 코드는 관리자 패널에서도 Django 1.4에서 잘 실행됩니다.
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)
모델을 삭제하기 전에 스토리지와 경로를 가져 오는 것이 중요합니다. 그렇지 않으면 모델이 삭제 된 경우에도 무효가 유지됩니다.
답변
당신은 필요 에 모두 실제 파일을 제거 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)
답변
pre_delete 또는 post_delete 신호 사용을 고려할 수 있습니다.
https://docs.djangoproject.com/en/dev/topics/signals/
물론 FileField 자동 삭제가 제거 된 동일한 이유가 여기에도 적용됩니다. 다른 곳에서 참조되는 파일을 삭제하면 문제가 발생합니다.
제 경우에는 모든 파일을 관리하는 전용 파일 모델이 있었기 때문에 이것이 적절 해 보였습니다.
참고 : 어떤 이유로 post_delete가 제대로 작동하지 않는 것 같습니다. 파일은 삭제되었지만 데이터베이스 레코드는 그대로 유지되었으므로 오류 조건에서도 예상했던 것과 완전히 반대입니다. pre_delete는 잘 작동합니다.
답변
조금 늦었을지도 모릅니다. 하지만 가장 쉬운 방법은 post_save 신호를 사용하는 것입니다. 신호는 QuerySet 삭제 프로세스 중에도 실행되지만 [model] .delete () 메서드는 QuerySet 삭제 프로세스 중에 실행되지 않으므로이를 재정의하는 가장 좋은 옵션은 아닙니다.
core / models.py :
from django.db import models
from django.db.models.signals import post_delete
from core.signals import delete_image_slide
SLIDE1_IMGS = 'slide1_imgs/'
class Slide1(models.Model):
title = models.CharField(max_length = 200)
description = models.CharField(max_length = 200)
image = models.ImageField(upload_to = SLIDE1_IMGS, null = True, blank = True)
video_embed = models.TextField(null = True, blank = True)
enabled = models.BooleanField(default = True)
"""---------------------------- SLIDE 1 -------------------------------------"""
post_delete.connect(delete_image_slide, Slide1)
"""--------------------------------------------------------------------------"""
core / signals.py
import os
def delete_image_slide(sender, **kwargs):
slide = kwargs.get('instance')
try:
os.remove(slide.image.path)
except:
pass