Django 2.x Lösung:
In Django 2 ist das Löschen von Dateien sehr einfach . Ich habe versucht, die folgende Lösung mit Django 2 und SFTP Storage sowie FTP STORAGE zu verwenden, und ich bin mir ziemlich sicher, dass sie mit allen anderen Speichermanagern funktioniert, die die deleteMethode implementiert haben . ( deleteMethode ist eine der storageabstrakten Methoden.)
Überschreiben Sie die deleteMethode des Modells so, dass die Instanz ihre FileFields löscht, bevor sie sich selbst löscht:
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()
Es funktioniert ziemlich einfach für mich. Wenn Sie vor dem Löschen überprüfen möchten, ob eine Datei vorhanden ist, können Sie diese verwenden storage.exists. zB self.song.storage.exists(self.song.name)gibt eine booleanDarstellung zurück, wenn das Lied existiert. So wird es aussehen:
def delete(self, using=None, keep_parents=False):
# assuming that you use same storage for all files in this model:
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 (zusätzlich):
Wie @HeyMan erwähnt, werden mit dieser Lösung beim Aufrufen Song.objects.all().delete()keine Dateien gelöscht! Dies geschieht, weil Song.objects.all().delete()die Löschabfrage von Default Manager ausgeführt wird . Wenn Sie also Dateien eines Modells mithilfe von objectsMethoden löschen möchten , müssen Sie einen benutzerdefinierten Manager schreiben und verwenden (nur um die Löschabfrage zu überschreiben):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
und um das CustomManagerdem Modell zuzuweisen, müssen Sie objectsin Ihrem Modell initialisieren:
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() # just add this line of code inside of your model
def delete(self, using=None, keep_parents=False):
self.song.storage.delete(self.song.name)
self.image.storage.delete(self.song.name)
super().delete()
Jetzt können Sie .delete()am Ende alle objectsUnterabfragen verwenden. Ich habe das einfachste geschrieben CustomManager, aber Sie können es besser machen, indem Sie etwas über gelöschte Objekte oder was auch immer Sie wollen zurückgeben.