Solution Django 2.x:
Il est très facile de gérer la suppression de fichiers dans Django 2 . J'ai essayé la solution suivante en utilisant Django 2 et le stockage SFTP ainsi que le STOCKAGE FTP, et je suis à peu près sûr que cela fonctionnera avec tous les autres gestionnaires de stockage qui ont implémenté la deleteméthode. (la deleteméthode est l'une des storageméthodes abstraites.)
Remplacez la deleteméthode du modèle de manière à ce que l'instance supprime ses FileFields avant de se supprimer:
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()
Cela fonctionne assez facilement pour moi. Si vous souhaitez vérifier si le fichier existe avant la suppression, vous pouvez utiliser storage.exists. par exemple self.song.storage.exists(self.song.name)retournera un booleanreprésentant si la chanson existe. Cela ressemblera donc à ceci:
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 (en plus):
Comme @HeyMan l'a mentionné, avec cette solution, l'appel Song.objects.all().delete()ne supprime pas les fichiers! Cela se produit car Song.objects.all().delete()exécute la requête de suppression de Default Manager . Donc, si vous voulez pouvoir supprimer les fichiers d'un modèle à l'aide de objectsméthodes, vous devez écrire et utiliser un gestionnaire personnalisé (juste pour remplacer sa requête de suppression):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
et pour affecter le CustomManagerau modèle, vous devez initialiser objectsà l' intérieur de votre modèle:
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()
Vous pouvez maintenant utiliser .delete()à la fin de toutes les objectssous-requêtes. J'ai écrit le plus simple CustomManager, mais vous pouvez le faire mieux en renvoyant quelque chose sur les objets que vous avez supprimés ou ce que vous voulez.