Django how to use post_save for upload image from another model

I am trying to copy image from my ProductImage models and upload it to my OrderItem models when any new order items will be create but got this error AttributeError: 'NoneType' object has no attribute 'image' but you can see my ProductImage model have image fields and also image exits for the current product which order is creating. here my two models:

#ProductImage Model
class ProductImage(models.Model):
    product = models.ForeignKey(Product,on_delete=models.CASCADE,blank=True,null=True)
    image = models.ImageField(upload_to=dynamic_upload_path)
    thumb_image =  models.ImageField(upload_to=dynamic_upload_path,blank=True,null=True)

#OrderItem models

class OrderItem(models.Model):
    order = models.ForeignKey(Order, on_delete=models.CASCADE,blank=True,null=True)
    product = models.ForeignKey(Product, on_delete=models.SET_NULL,blank=True,null=True)
    product_image = models.ForeignKey(ProductImage, on_delete=models.SET_NULL,blank=True,null=True) 
    order_image_file = models.ImageField(blank=True,null=True,upload_to=orderImage_upload_path) 

my signals:

@receiver(post_save, sender=OrderItem)
def OrderItemSignals(sender, instance, created,**kwargs):
    if created:
        instance.order_image_file = instance.product_image.image

so basically when any order item will be create I want to fire my post save for copy image from my product image models and upload it to my order item models image fields.

Hi,

Your OrderItem model definition allows for product_image to be empty (null=True), so having it set to None may be normal.

Can you share the code where OrderItem is created, showing whether a ProductImage is affected to the model instance or not.

Also, as it has been said numerous times in this forum, and as it is stated is django documentation (see the first warning at Signals | Django documentation | Django), you’d rather directly set the order_image_file when creating the OrderItem instead of using a signal. E.g.: if you do:

OrderItem.objects.create(
    order=some_order,
    product=some_product,
    product_image=some_product_image,
)

You’re probably able to do the following:

OrderItem.objects.create(
    order=some_order,
    product=some_product,
    product_image=some_product_image,
    order_image_file=some_product_image.image,
)

This would also probably help having a cleaner model definition (without null=True on each field which look like weird and may be there just for managing the transiant state of the object between its first save with empty fields and their population by a post_save signal).

Finally, having the same image as the ProductImage on OrderItem looks like a redundancy. One case where I can see this as useful is when ProductImage.image may change in the future.and we want to keep the image on OrderItem the same as when OrderItem was created. But, in this case, I wonder if the foreign key to ProductImage is necessary!

1 Like