Django 2.x Solution :
Il est très facile de gérer la suppression de fichiers en Django 2 . J'ai essayé la solution suivante en utilisant Django 2 et SFTP Storage et aussi FTP STORAGE, et je suis presque sûr qu'elle fonctionnera avec n'importe quel autre gestionnaire de stockage qui implémente l'option delete
méthode. ( delete
est l'une des méthodes de storage
méthodes abstraites qui sont censées supprimer le fichier du stockage, physiquement !)
Remplacer le delete
du modèle de manière à ce que l'instance supprime ses FileFields avant de se supprimer elle-même :
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.image.name)
super().delete()
Cela fonctionne assez facilement pour moi. Si vous voulez 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):
# 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.image.name)
super().delete()
EDIT (En complément) :
Como @HeyMan mentionné, avec cette solution qui appelle Song.objects.all().delete()
ne supprime pas les fichiers ! Cela se produit parce que Song.objects.all().delete()
exécute une requête de suppression de Gestionnaire par défaut . Ainsi, si vous voulez être en mesure de supprimer les fichiers d'un modèle en utilisant l'option objects
vous devez écrire et utiliser un Gestionnaire sur mesure (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 attribuer 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() # 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.image.name)
super().delete()
Vous pouvez maintenant utiliser .delete()
à la fin de tout objects
sous-requêtes. J'ai écrit la plus simple CustomManager
mais vous pouvez faire mieux en renvoyant quelque chose sur les objets que vous avez supprimés ou ce que vous voulez.