mi ProductImagesmodelo, hice algunos campos para almacenar varios tipos de la misma imagen, como:
class ProductImages(models.Model):
product = models.ForeignKey(Product, on_delete=models.CASCADE)
#This field is used in form
image_file_w200_png = models.ImageField(
verbose_name = "Selecione a imagem",
upload_to=upload_to_image_file_w200_png,
null=True,
blank=True,
default='magickhat-profile.jpg'
)
#This field is not used in forms
image_file_w480_png = models.ImageField(
upload_to=upload_to_image_file_w480_png,
null=True,
blank=True,
default='magickhat-profile.jpg'
)
...
def save(self, *args, **kwargs):
try:
this = ProductImages.objects.get(id=self.id)
if this.image_file_w200_png != self.image_file_w200_png:
this.image_file_w200_png.delete(save=False)
if this.image_file_w480_png != self.image_file_w480_png:
this.image_file_w480_png.delete(save=False)
except:
pass
# resize function on utils.py
image_manipulation(self)
if self.id is None:
saved_image_w200_png = self.image_file_w200_png
self.image_file_w200_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w200_png = saved_image_w200_png
saved_image_w480_png = self.image_file_w480_png
self.image_file_w480_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w480_png = saved_image_w480_png
if 'force_insert' in kwargs:
kwargs.pop('force_insert')
super(ProductImages, self).save(*args, **kwargs)Bueno, la idea es que cuando el usuario sube una imagen desde image_file_w200_pngel campo, la imagen se redimensiona a varias dimensiones, y guardo esas otras imágenes en otros campos comoimage_file_w480_png
Mi problema real consiste en upload_to, como podemos ver en los documentos , upload_to may also be a callable, such as a function. Así que hice mi propia función en utils.pycada upload_tocampo.
utils.py - verifique los comentarios por favor
# Here instance.id have value
def upload_to_image_file_w200_png(instance, filename):
ext = filename.split('.')[-1]
filename = instance.product.slug+"_"+str(instance.id)+"_w200_png."+ext
return 'user_{0}/{1}/{2}/{3}'.format(instance.product.user.id, instance.product.id, instance.id, filename)
"""
Here instance(ProductImages) is not initialized,value is none
For example in php i just store $_SESSION['id'] = instance.id in above function and call this session here, idk how python do equivalent, not even if that is the right approach
"""
def upload_to_image_file_w480_png(instance, filename):
ext = filename.split('.')[-1]
filename = instance.product.slug+"_"+str(instance.id)+"_w480_png."+ext
return 'user_{0}/{1}/{2}/{3}'.format(instance.product.user.id, instance.product.id, instance.id, filename)
def image_manipulation(self):
image_original = self.image_file_w200_png
#image_resize_w200 to png
image_open_w200_png = Image.open(image_original)
image_output_w200_png = BytesIO()
image_resize_w200_png = image_open_w200_png.resize((200,300))
image_resize_w200_png.save(image_output_w200_png, format="PNG", optimize=False, quality=10)
image_output_w200_png.seek(0)
self.image_file_w200_png = InMemoryUploadedFile(image_output_w200_png,'ImageField',"%s.png" %self.image_file_w200_png.name.split('.')[0],'image/png',sys.getsizeof(image_output_w200_png), None)
#resize image small width 480 to png
image_open_w480_png = Image.open(image_original)
image_output_w480_png = BytesIO()
image_basewidth_w480_png = 480
image_wpercent_w480_png = (image_basewidth_w480_png / float(image_open_w480_png.size[0]))
image_hsize_w480_png = int((float(image_open_w480_png.size[1]) * float(image_wpercent_w480_png)))
image_resize_w480_png = image_open_w480_png.resize((image_basewidth_w480_png,image_hsize_w480_png), Image.LANCZOS)
image_resize_w480_png.save(image_output_w480_png, format="PNG", optimize=True, quality=10)
image_output_w480_png.seek(0)
self.image_file_w480_png = InMemoryUploadedFile(image_output_w480_png,'ImageField',"%s.png" %self.image_file_w480_png.name.split('.')[0],'image/png',sys.getsizeof(image_output_w480_png), None)el problema es que instance.ides la idimagen del campo, pero el único campo que se instancia es image_file_w200_pngel campo, image_file_w480_pngno lo es, entonces, ¿cómo puedo usar la función instance.idfrom upload_to_image_file_w200_pngen la upload_to_image_file_w480_pngfunción?
upload_tose llama para ambos ImageFields cuando llamas super(ProductImages, self).save(*args, **kwargs).
Establecer self.image_file_w480_png = Noneantes super(ProductImages, self).save(*args, **kwargs).
if self.id is None:
# saved_image_w200_png = self.image_file_w200_png
# self.image_file_w200_png = None
# super(ProductImages, self).save(*args, **kwargs)
# self.image_file_w200_png = saved_image_w200_png
# saved_image_w480_png = self.image_file_w480_png
# self.image_file_w480_png = None
# super(ProductImages, self).save(*args, **kwargs)
# self.image_file_w480_png = saved_image_w480_png
saved_image_w200_png = self.image_file_w200_png
saved_image_w480_png = self.image_file_w480_png
self.image_file_w200_png = None
self.image_file_w480_png = None
super(ProductImages, self).save(*args, **kwargs)
self.image_file_w200_png = saved_image_w200_png
self.image_file_w480_png = saved_image_w480_png