ruchej
@ruchej
Конструктор мебели. Пишу макросы для К3-Мебель

Как правильно сохранить результат изменения значения в БД?

В модели переопределяю функцию 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)
  • Вопрос задан
  • 225 просмотров
Пригласить эксперта
Ответы на вопрос 1
Знакомься, рекурсия:
def foo():
    foo()


Переопределение метода:
class Bar():
    def foo(self, ...):
        pass

class Foo(Bar):
    ...
    def foo(self, ...):
        super(Foo, self).foo(...)
        pass


Еще один способ впасть в рекурсию:
class Foo(models.Model):
    ...
    pass

@receiver(post_save, sender=Foo)
def foo_bar(sender, instance, **kwargs):
    instance.save()
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы