Importing Images in Odoo

Handle various import for many occasions

Amirul M.
3 min readAug 13, 2020
Where should I place my extension in the world full of Spaghetti Code? Photo by Immo Wegmann on Unsplash

Odoo has provided us an easy way to import data from excel or CSV file. It can be accessed from all of existing tree’s menu. I just need to click import button, select a file, and then import. Just like that.

The questions are:

  1. How should I write in the file so it can automatically be recognized?
  2. Can I import images too? From URL or local images?

Here’s the answers:

  1. First, place the field name in the header. Then, place the data below it by the corresponding header. For example, below header ‘name’, I write ‘Product A’ because it is string type field. For another type, make sure the value you write is same as the type of its field.
  2. Yes, of course I can. But unfortunately, existing Odoo doesn’t support it. WHATTT? So how can I??? Easy boy, I just need to find the correct custom addons in their community, or… I can just create by myself. I choose the latter.

How

  • Find the part of code that responsible for doing import. I find it placed under base_import.import module. So I start with extend it.
class ImportInherit(models.TransientModel):
_inherit = 'base_import.import'
  • Then, where should I write my future code? After a series of debugging, I can write it after _parse_import_data method. So extend this.
@api.multi
def _parse_import_data(self, data, import_fields, options):
data = super(ImportInherit, self)._parse_import_data(data, import_fields, options)
for k, v in enumerate(data[0]):
if v and type(v) == str:
if "http://" in v or "https://" in v or v.split('.')[-1] in ['png', 'jpg', 'jpeg']:
res = self.convert_image(v)
data[0][k] = res
return data
  • Because of I want to execute my code just after executing that existing method, I call it after its super.
  • I also write series of validations for just string type only, only if there are ‘http’ or ‘https’ in it (for URL importing), and only if ended by image extensions (png, jpg, jpeg, for local importing).
  • What’s the written inside convert_image method?
@api.multi
def convert_image(self, image_path):
if "http://" in image_path or "https://" in image_path:
try:
link = urllib.request.urlopen(image_path).read()
image_base64 = base64.b64encode(link)
return image_base64
except Exception:
raise Warning("Please provide correct URL for product '%s' or check your image size.!")
elif image_path.split('.')[-1] in ['png', 'jpg', 'jpeg']:
with open(image_path, 'rb') as image:
image_base64 = image.read()
image_base64 = base64.b64encode(image_base64)
return image_base64
  • With the help of urllib and base64 library, in the first condition, I can read image from given URL and encode it so it can be saved in database. In the second condition, I can read image from given local path and then the same as before, encode it.

The Last

The hardest part is not writing the code, but when I need to find where to place it because you need to read existing code first that written by SOMEONE ELSE.

--

--