Soluzione Django 2.x:
È molto facile gestire l'eliminazione dei file in Django 2 . Ho provato la seguente soluzione utilizzando Django 2 e SFTP Storage e anche FTP STORAGE, e sono abbastanza sicuro che funzionerà con qualsiasi altro gestore di archiviazione che abbia implementato il delete
metodo. (il delete
metodo è uno dei storage
metodi astratti.)
Sostituisci il delete
metodo del modello in modo che l'istanza elimini i propri FileField prima di eliminarsi:
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()
Funziona abbastanza facilmente per me. Se vuoi controllare se il file esiste prima dell'eliminazione, puoi usare storage.exists
. es. self.song.storage.exists(self.song.name)
restituirà una boolean
rappresentazione se la canzone esiste. Quindi sarà simile a questo:
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 (in aggiunta):
Come menzionato da @HeyMan , con questa soluzione la chiamata Song.objects.all().delete()
non cancella i file! Ciò sta accadendo perché Song.objects.all().delete()
sta eseguendo la query di eliminazione di Default Manager . Quindi, se vuoi essere in grado di eliminare i file di un modello utilizzando objects
metodi, devi scrivere e utilizzare un gestore personalizzato (solo per sovrascrivere la sua query di eliminazione):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
e per assegnare il CustomManager
al modello, devi siglare objects
all'interno del tuo modello:
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()
Ora puoi usare .delete()
alla fine di qualsiasi objects
sottoquery. Ho scritto il più semplice CustomManager
, ma puoi farlo meglio restituendo qualcosa sugli oggetti che hai cancellato o quello che vuoi.