'Django pass id from instance to not instantiated model field

Im my ProductImages model i made some fields to store various types of same image, like:

models.py

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 ideia is when user upload a image from image_file_w200_png field, the image is resized to various dimensions, and i save that other images in other fields like image_file_w480_png

My actual problem consiste in upload_to, as we can see in docs, upload_to may also be a callable, such as a function. So i made my own function in utils.py to upload_to to each field.

utils.py - check comments pls

# 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, instance.id is the id of field image, but the only field that is instantiated is image_file_w200_png field, the image_file_w480_png is not, so how can i use the instance.id from upload_to_image_file_w200_png function in upload_to_image_file_w480_png function?



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source