[Django]-How to programatically add product images in django oscar?

5👍

I think you can do it like this using File class:

from django.core.files import File

for product in my_product_import_list:
    ...
    product_entry = Product()
    product_entry.title = my_product_title
    product_entry.product_class = my_product_class
    product_entry.category = my_category
    image = File(open("product_images/my_product_filename.jpg", 'rb'))
    product_entry.primary_image = image
    product_entry.save()

Update

probably you should use OSCAR_MISSING_IMAGE_URL in settings:

OSCAR_MISSING_IMAGE_URL = "product_images/my_product_filename.jpg"  # relative path from media root

Alternatively, you can use ProductImage, like this:

    from oscar.apps.catalogue.models import ProductImage

    product_entry = Product()
    product_entry.title = my_product_title
    product_entry.product_class = my_product_class
    product_entry.category = my_category
    product_entry.save()
    product_image = ProductImage()
    image = File(open("product_images/my_product_filename.jpg", 'rb'))
    product_image.original = image
    product_image.caption = "Some Caption"
    product_image.product = product_entry
    product_image.save()

As ProductImage has a ForignKey relation to Product Model, and primary_image is a method in Product model, which takes image from ProductImage model, and returns the first one(ProductImage objects ordered by display_order field in that field)

👤ruddra

0👍

Not entirely sure how helpful this will be to anyone, but I was getting a SuspiciousFileOperation Exception when using @ruddra’s answer here, even though I was using a tempfile within the media root…

File "/Users/user/Documents/project/venv/lib/python3.7/site-packages/django/core/files/utils.py", line 19, in validate_file_name
    "Detected path traversal attempt in '%s'" % name
django.core.exceptions.SuspiciousFileOperation: Detected path traversal attempt in '/Users/user/Documents/project/media/images/tmp6xem6hvs'

Fixed by first saving the image (got the idea from this SO answer), then saving the product image:

import tempfile
from django.core.files.images import ImageFile
...
lf = tempfile.NamedTemporaryFile(dir='media')
f = open('<full_path_to_project>/media/images/my_product_filename.jpg', 'rb')
lf.write(f.read())
image = ImageFile(lf)
product_image = ProductImage()
product_image.caption = "some caption"
product_image.product = product_entry
product_image.original = image
product_image.original.save('my_product_filename.jpg', image) # <-----
product_image.save()
...
👤kt-0

Leave a comment