В модели переопределяю функцию save. Если я делаю изменение значения поля, например, self.imagepath.name = new_db_imagepath, то это изменение надо сохранить. Если сохранить изменения, как это написано в примерах djangobook, т.е. self.save(), то весь процесс зависнет. Тогда для сохранения подставил super(Images, self).save(*args, **kwargs) и получил нужное.
Так почему же self.save() зациклило и как правильно сохранять изменения?
class Images(models.Model):
'''Таблица путей изображений'''
furnproduct = models.ForeignKey(FurnitureProduct, on_delete=models.CASCADE, verbose_name='Изделие')
imagepath = models.ImageField(upload_to=PathAndRename('images'), verbose_name='Изображение')
def save(self, *args, **kwargs):
# Сначала - обычное сохранение
super(Images, self).save(*args, **kwargs)
# Проверяем, указана ли картинка
if self.imagepath:
filepath = self.imagepath.path
dirpath = os.path.dirname(filepath)
ext = filepath.split('.')[-1]
new_file_name = '{}.{}'.format(self.pk, ext)
db_imagepath = self.imagepath.name
list_imagepath = db_imagepath.split('/')[:-1]
list_imagepath.append(new_file_name)
new_db_imagepath = '/'.join(list_imagepath)
width = self.imagepath.width
height = self.imagepath.height
ratio = width/height
# Может, и не надо ничего менять?
if (width > MAX_WIDTH_IMAGE) or (height > MAX_HEIGHT_IMAGE):
image = Image.open(filepath)
# resize - безопасная функция, она создаёт новый объект, а не
# вносит изменения в исходный, поэтому так
if ratio > 1:
image = image.resize((MAX_WIDTH_IMAGE, round(MAX_WIDTH_IMAGE/ratio)), Image.ANTIALIAS)
else:
image = image.resize((round(MAX_HEIGHT_IMAGE*ratio), MAX_HEIGHT_IMAGE), Image.ANTIALIAS)
image.save(os.path.join(dirpath, new_file_name))
self.imagepath.name = new_db_imagepath
super(Images, self).save(*args, **kwargs)