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 delete
méthode. (la delete
méthode est l'une des storage
méthodes abstraites.)
Remplacez la delete
mé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 boolean
repré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 objects
mé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 CustomManager
au 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 objects
sous-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.