Solução Django 2.x:
É muito fácil lidar com a exclusão de arquivos no Django 2 . Eu tentei seguir a solução usando Django 2 e SFTP Storage e também FTP STORAGE, e tenho certeza de que funcionará com qualquer outro gerenciador de armazenamento que implementou o delete
método. ( delete
método é um dosstorage
métodos abstratos).
Substitua o delete
método do modelo de forma que a instância exclua seus FileFields antes de excluir a si mesma:
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 muito fácil para mim. Se você quiser verificar se o arquivo existe antes da exclusão, você pode usar storage.exists
. por exemplo self.song.storage.exists(self.song.name)
, retornará um boolean
representando se a música existe. Então, ficará assim:
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.song.name)
super().delete()
EDITAR (além):
Como @HeyMan mencionou, com esta solução, chamar Song.objects.all().delete()
não exclui arquivos! Isso está acontecendo porque Song.objects.all().delete()
está executando a consulta de exclusão do Default Manager . Portanto, se você deseja excluir arquivos de um modelo usando objects
métodos, deve escrever e usar um gerenciador personalizado (apenas para substituir sua consulta de exclusão):
class CustomManager(models.Manager):
def delete(self):
for obj in self.get_queryset():
obj.delete()
e para atribuir o CustomManager
ao modelo, você deve rubricar objects
em seu 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() # 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.song.name)
super().delete()
Agora você pode usar .delete()
no final de quaisquer objects
subconsultas. Eu escrevi o mais simples CustomManager
, mas você pode fazer melhor retornando algo sobre os objetos que você excluiu ou o que quiser.