I am currently programatically importing products into my product catalog, however, I am having difficulty uploading images for each product. Here's what my code looks like:
# frobshop/custom_utils/product_importer.py
from oscar.apps.catalogue.models import Product
...
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
product_entry.primary_image = "product_images/my_product_filename.jpg"
product_entry.save()
The details such as product title and product class are successfully saved when I check using the development server, however, I am unsure how to set an image for each product.
The entire product_images
folder was initially located outside of my media
directory, but since I wasn't getting any results, I copy pasted the entire folder of my images into the media
directory but still with no results. I am assuming that quite a number of steps are being skipped, and maybe there's a convention on how to arrange images in the media directory. However, I am not sure where to find these steps and conventions.
Here's the portion of my settings.py
file that deals with my installed apps, the media directory, and static files:
# frobshop/frobshop/settings.py
...
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
'django.contrib.flatpages',
'compressor',
'widget_tweaks',
] + get_core_apps(['custom_apps.shipping', 'custom_apps.payment', 'custom_apps.checkout'])
...
STATIC_ROOT = 'static'
STATIC_URL = '/static/'
MEDIA_ROOT = 'media'
MEDIA_URL = '/media/'
For further clarity, here's my urls.py
from django.contrib import admin
from django.urls import path
from django.conf.urls import include, url
from oscar.app import application
from django.conf import settings
from django.conf.urls.static import static
urlpatterns = [
url(r'^i18n/', include('django.conf.urls.i18n')),
path('admin/', admin.site.urls),
url(r'', application.urls),
] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT)
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()
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)