Rozwiązanie Django 2.x:
Usuwanie plików w Django 2 jest bardzo łatwe . Wypróbowałem następujące rozwiązanie wykorzystujące Django 2 i SFTP Storage, a także FTP STORAGE i jestem prawie pewien, że będzie działać z każdym innym menedżerem pamięci, który zaimplementował tę delete
metodę. ( delete
metoda jest jedną zstorage
metod abstrakcyjnych).
Zastąp delete
metodę modelu w taki sposób, że instancja usuwa swoje FileFields przed usunięciem siebie:
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()
U mnie działa to całkiem łatwo. Jeśli chcesz sprawdzić, czy plik istnieje przed usunięciem, możesz użyć storage.exists
. np. self.song.storage.exists(self.song.name)
zwróci boolean
reprezentację, jeśli piosenka istnieje. Więc będzie to wyglądać tak:
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()
EDYCJA (dodatkowo):
Jak wspomniał @HeyMan , wywołanie tego rozwiązania Song.objects.all().delete()
nie powoduje usunięcia plików! Dzieje się tak, ponieważ Song.objects.all().delete()
jest uruchomione zapytanie usuwające Menedżera domyślnego . Więc jeśli chcesz mieć możliwość usuwania plików modelu za pomocą objects
metod, musisz napisać i używać Custom Manager (tylko do nadpisania jego zapytania usuwającego):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
i aby przypisać CustomManager
do modelu, musisz zainicjować objects
wewnątrz swojego modelu:
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()
Teraz możesz użyć .delete()
na końcu dowolnych objects
pod-zapytań. Napisałem najprostszy CustomManager
, ale możesz to zrobić lepiej, zwracając coś o usuniętych obiektach lub cokolwiek chcesz.