Solusi Django 2.x:
Sangat mudah menangani penghapusan file di Django 2 . Saya telah mencoba mengikuti solusi menggunakan Django 2 dan Penyimpanan SFTP dan juga PENYIMPANAN FTP, dan saya cukup yakin bahwa ini akan bekerja dengan manajer penyimpanan lain yang menerapkan deletemetode. ( deletemetode adalah salah satu storagemetode abstrak.)
Ganti deletemetode model sedemikian rupa sehingga instance menghapus FileFields sebelum menghapusnya sendiri:
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()
Ini bekerja sangat mudah bagi saya. Jika Anda ingin memeriksa apakah file sudah ada sebelum dihapus, Anda dapat menggunakan storage.exists. mis. self.song.storage.exists(self.song.name)akan mengembalikan booleanrepresentasi jika lagu tersebut ada. Jadi akan terlihat seperti ini:
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()
EDIT (Sebagai Tambahan):
Seperti yang disebutkan @HeyMan , dengan solusi ini, pemanggilan Song.objects.all().delete()tidak menghapus file! Ini terjadi karena Song.objects.all().delete()menjalankan query delete dari Default Manager . Jadi, jika Anda ingin menghapus file model dengan menggunakan objectsmetode, Anda harus menulis dan menggunakan Manajer Kustom (hanya untuk menimpa kueri penghapusannya):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
dan untuk menetapkan CustomManagerke model, Anda harus melakukan inisial objectsdi dalam model Anda:
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()
Sekarang Anda dapat menggunakan .delete()di akhir objectssub-kueri apa pun . Saya menulis yang paling sederhana CustomManager, tetapi Anda dapat melakukannya lebih baik dengan mengembalikan sesuatu tentang objek yang Anda hapus atau apa pun yang Anda inginkan.