Solución Django 2.x:
Es muy fácil manejar la eliminación de archivos en Django 2 . Intenté seguir la solución usando Django 2 y SFTP Storage y también FTP STORAGE, y estoy bastante seguro de que funcionará con cualquier otro administrador de almacenamiento que haya implementado el delete
método. (el delete
método es uno de los storage
métodos abstractos).
Anule el delete
método del modelo de forma que la instancia elimine sus FileFields antes de borrarse a sí misma:
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()
Funciona bastante fácil para mí. Si desea verificar si el archivo existe antes de eliminarlo, puede usar storage.exists
. por ejemplo self.song.storage.exists(self.song.name)
, devolverá una boolean
representación si la canción existe. Entonces se verá así:
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()
EDITAR (además):
Como mencionó @HeyMan , con esta solución, la llamada Song.objects.all().delete()
no elimina archivos. Esto sucede porque se Song.objects.all().delete()
está ejecutando la consulta de eliminación del Administrador predeterminado . Entonces, si desea poder eliminar archivos de un modelo mediante el uso de objects
métodos, debe escribir y usar un Administrador personalizado (solo para anular su consulta de eliminación):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
y para asignar el CustomManager
al modelo, debe poner sus iniciales objects
dentro de su modelo:
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()
Ahora puede usar .delete()
al final de cualquier objects
subconsulta. Escribí lo más simple CustomManager
, pero puedes hacerlo mejor devolviendo algo sobre los objetos que eliminaste o lo que quieras.