Рішення Django 2.x:
Видалити файли в Django 2 дуже просто . Я спробував наступне рішення, використовуючи Django 2 і SFTP Storage, а також FTP STORAGE, і я впевнений, що воно буде працювати з будь-якими іншими менеджерами сховищ, які реалізували delete
метод. ( delete
метод є одним із storage
абстрактних методів.)
Перевизначте delete
метод моделі таким чином, що екземпляр видаляє свої FileFields перед самим видаленням:
class Song(models.Model):
name = models.CharField(blank=True, max_length=100)
author = models.ForeignKey(User, to_field='id', related_name="id_user2")
song = models.FileField(upload_to='/songs/')
image = models.ImageField(upload_to='/pictures/', blank=True)
date_upload = models.DateField(auto_now_add=True)
def delete(self, using=None, keep_parents=False):
self.song.storage.delete(self.song.name)
self.image.storage.delete(self.song.name)
super().delete()
Для мене це працює досить легко. Якщо ви хочете перевірити, чи існує файл перед видаленням, ви можете використовувати storage.exists
. наприклад self.song.storage.exists(self.song.name)
, поверне boolean
репрезентацію, якщо пісня існує. Тож це буде виглядати так:
def delete(self, using=None, keep_parents=False):
storage = self.song.storage
if storage.exists(self.song.name):
storage.delete(self.song.name)
if storage.exists(self.image.name):
storage.delete(self.song.name)
super().delete()
РЕДАГУВАТИ (Додатково):
Як зазначав @HeyMan , за допомогою цього рішення виклик Song.objects.all().delete()
файлів не видаляє! Це відбувається, оскільки Song.objects.all().delete()
запущений запит на видалення Диспетчера за замовчуванням . Отже, якщо ви хочете мати можливість видаляти файли моделі за допомогою objects
методів, ви повинні написати та використовувати користувальницький менеджер (лише для того, щоб замінити його запит на видалення):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
і для присвоєння CustomManager
моделі, ви повинні ініціювати objects
всередині вашої моделі:
class Song(models.Model):
name = models.CharField(blank=True, max_length=100)
author = models.ForeignKey(User, to_field='id', related_name="id_user2")
song = models.FileField(upload_to='/songs/')
image = models.ImageField(upload_to='/pictures/', blank=True)
date_upload = models.DateField(auto_now_add=True)
objects = CustomManager()
def delete(self, using=None, keep_parents=False):
self.song.storage.delete(self.song.name)
self.image.storage.delete(self.song.name)
super().delete()
Тепер ви можете використовувати .delete()
в кінці будь objects
-які підзапити. Я писав найпростіший CustomManager
, але ви можете зробити це краще, повернувши щось про об’єкти, які ви видалили, або що завгодно.