my ProductImages model, I made some fields to store multiple types of the same image, like:
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) Well the idea is that when the user uploads an image from the image_file_w200_png field, the image is resized to various dimensions, and I image_file_w480_png
My real problem involves upload_to , as we can see in the docs , upload_to may also be a callable, such as a function . So I made my own function in utils.py each upload_to field.
utils.py - check comments please
# 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) the problem is that instance.id is the id of the field, but the only field that is instantiated is the image_file_w200_png field, image_file_w480_png not, so how can I use the function instance.id from upload_to_image_file_w200_png in the upload_to_image_file_w480_png function?
upload_to is called for both ImageField s when you call super(ProductImages, self).save(*args, **kwargs) .
Set self.image_file_w480_png = None before 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