#python #django #image #delete-file #imagefield
#python #django #изображение #удалить-файл #imagefield
Вопрос:
У меня есть эта модель:
class UserProfile(models.Model):
"""(UserProfile description)"""
user = models.ForeignKey(User)
image = models.ImageField(upload_to=upload_to)
def save(self):
os.unlink(self.image.path)
super(UserProfile, self).save()
Скрипт завершает работу с unlink()
методом с ошибкой и сообщает, что файл не может быть найден. Есть идеи?
Ошибка гласит
(2, ‘Такого файла или каталога нет’)
Ответ №1:
Вам нужна более конкретная отладка. Кроме того, способ, которым вы написали код, вероятно, гарантирует возникновение ошибок. Я не совсем уверен, но я не удивлюсь, если значение для UserProfile.image не задано до создания записи UserProfile.
Поэтому я бы переписал ваш код таким образом:
class UserProfile(models.Model):
user = models.ForeignKey(User)
image = models.ImageField(upload_to=upload_to)
def save(self):
if self.image.path:
try:
os.unlink(self.image.path)
except Exception, inst:
raise Exception("Unable to delete %s. Error: %s" % (self.image.path, inst))
super(UserProfile, self).save()
Обновить
Теперь, когда я думаю об этом, имеет смысл, что как только вы вызываете save, новая информация уже находится в self.image. Если ваша цель — удалить старые изображения при сохранении нового, вам нужно будет использовать сигнал pre_save в Django для извлечения старой записи (и, следовательно, старого пути к изображению) перед сохранением изображения. Теоретически, вы могли бы поместить это в save
метод UserProfile
модели, но поскольку это предназначено как побочное действие, которое напрямую не влияет на текущую запись, я бы сохранил его отдельно.
Вот пример реализации:
from django.db.models import signals
def delete_old_image(sender, instance, using=None):
try:
old_record = sender.objects.get(pk=instance.pk)
os.unlink(old_record.image.path)
except sender.DoesNotExist:
pass
signals.pre_save.connect(delete_old_image, sender=UserProfile)
Вы бы поместили это в свой models.py
файл.
Комментарии:
1. Хорошо, я к чему-то приближаюсь. Получается self.image. путь ссылается на новое изображение, а не на то, которое уже существует. Есть ли причина, почему это так?
2. Я бы предположил, что это связано с тем фактом, что значение для self.image устанавливается перед сохранением.
save
функция не принимает набор значений и не помещает его в запись модели. Скорее, он сохраняет в базе данных значения, которые уже есть в модели. Если вы серьезно относитесь к выполнению этого удаления, вы хотите использоватьpre_save
сигнал, описанный здесь: docs.djangoproject.com/en/dev/ref/signals /… . Я обновлю свой ответ.