1. 직접 구현
원하는 모델의 save method를 아래와 같이 오버라이드 해주면 된다.
import sys
class Blablabla(model.model):
def save(self, *args, **kwargs):
#해당하는 model 클래스를 갖고온다.
mod = getattr(sys.modules[__name__], self._meta.object_name)
try:
obj = mod.objects.get(id=self.id)
except:
obj = None
else:
for field in obj._meta.fields:
field_type = field.get_internal_type()
#필드 이름이 FileField나 ImageField 라면
if field_type == 'FileField' or field_type == 'ImageField':
origin_file = getattr(obj, field.name)
new_file = getattr(self, field.name)
#기존 필드랑 새로운 필드를 비교해서 다르다면 삭제해준다
if origin_file != new_file:
#그냥 url을 사용하면 경로를 못찾는다.
path = '.' + origin_file.url
if os.path.isfile(path):
os.remove(path)
super(mod, self ).save(*args, **kwargs)
return
code.djangoproject.com/ticket/6157
2. 패키지 사용하기
github.com/un1t/django-cleanup
3. Signal 사용하기(가장 추천하는 방법)
from django.db import models
class Event(models.model):
planImage = models.ImageField("행사계획 이미지", upload_to=ImageDirectory, height_field=None, width_field=None, blank=True, null=True)
buttonImage = models.ImageField("버튼 이미지", upload_to=ImageDirectory, height_field=None, width_field=None, max_length=None, help_text="등록하기 버튼 이미지 입니다.(필수항목) 권장 사이즈:400 x 120")
footerImage = models.ImageField("바닥 이미지", upload_to=ImageDirectory, height_field=None, width_field=None, null=True, help_text="등록페이지의 바닥에 위치하는 이미지 입니다.(필수항목) 권장 사이즈: 1200 x 75")
regCompleteImage = models.ImageField("등록 완료 이미지", upload_to=ImageDirectory, height_field=None, width_field=None, null=True, help_text="등록을 완료하면 보이는 이미지 입니다.(필수항목) 권장 사이즈:1000 x 500")
endImage = models.ImageField("행사 종료 이미지", upload_to=ImageDirectory, height_field=None, width_field=None, help_text="행사가 종료된 후 띄어지는 이미지 입니다.(필수항목) 권장 사이즈:800 x 400")
@receiver(models.signals.pre_save, sender=Event)
def auto_delete_file_on_save(sender, instance, **kwargs):
if not instance.pk:
return False
try:
old_obj = sender.objects.get(pk=instance.pk)
except sender.DoesNotExist:
return False
for field in instance._meta.fields:
field_type = field.get_internal_type()
if field_type == 'FileField' or field_type == 'ImageField':
origin_file = getattr(old_obj, field.name)
new_file = getattr(instance, field.name)
print(origin_file, new_file)
if origin_file != new_file and os.path.isfile(origin_file.path):
os.remove(origin_file.path)
@receiver(models.signals.post_delete, sender=Event)
def auto_delete_file_on_delete(sender, instance, **kwargs):
for field in instance._meta.fields:
field_type = field.get_internal_type()
if field_type == 'FileField' or field_type == 'ImageField':
origin_file = getattr(instance, field.name)
if origin_file and os.path.isfile(origin_file.path):
os.remove(origin_file.path)
'Web Programming > Django' 카테고리의 다른 글
[장고백서] 필드에서 작성한 validator가 작동을 안할 때 (0) | 2021.04.09 |
---|---|
[Django] Form 동적으로 생성하기 (0) | 2021.03.27 |
[Django] python manage.py를 하면 무슨 일이? (0) | 2021.02.26 |
[Django] Django Template 인덱스 사용하기 (0) | 2021.02.22 |
[Django] Django에서 DB 엑셀 파일 생성하는 방법 (2) | 2021.02.17 |