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 delete
Methode implementiert haben . ( delete
Methode ist eine der storage
abstrakten Methoden.)
Überschreiben Sie die delete
Methode 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 boolean
Darstellung 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 objects
Methoden 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 CustomManager
dem Modell zuzuweisen, müssen Sie objects
in 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 objects
Unterabfragen 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.