Answer the question
In order to leave comments, you need to log in
How to save the result of changing the value in the database?
In the model, I override the save function. If I make a change to the value of a field, for example, self.imagepath.name = new_db_imagepath, then this change must be saved. If you save the changes, as it is written in the djangobook examples, i.e. self.save() then the whole process will hang. Then, to save, I substituted super(Images, self).save(*args, **kwargs) and got what I needed.
So why is self.save() looping and what is the correct way to save changes?
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)
Answer the question
In order to leave comments, you need to log in
Meet Recursion:
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()
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question