OWL ‐ Uploading Files - vec-ltd/odoo-docs GitHub Wiki
Whether it is an image or a pdf file, a file it remains and what follows are some of the challenges and solutions for them.
You can have some code in your .js file of your component which will render a built-in Odoo action window. This way is the easiest as you can just select the image you wish to upload and Odoo takes care of the rest.

async toQuestionFormView (question) {
this.action.doAction({
name: "Question Details",
type: "ir.actions.act_window",
res_model: "audit.snapshot_question",
views: [[false, "form"]],
target: "new",
res_id: question.id,
})
}
Or you would like an html input tag from which to select a file - This is the much harder way.

<form method="post" enctype="multipart/form-data">
<input
type="file"
t-on-change="event => this.onChangeAttach(event, {...question})"
id="image-upload"
name="image-upload"
accept="image/*" />
</form>
async onChangeAttach(event, question) {
const pictureFile = event.target.files[0]
const base64EncodedFile = await this.convertFileToBase64(pictureFile)
this.state.fileToUpload = base64EncodedFile
}
convertFileToBase64 = (file) => {
return new Promise((resolve, reject) => {
const fileReader = new FileReader()
fileReader.readAsDataURL(file)
fileReader.onload = () => {
resolve(fileReader.result)
}
fileReader.onerror = (error) => {
reject(error)
}
})
}
// A simple function which calls the overwritten `write` method of the `SnapshotQuestion` class
async saveQuestionChanges (question) {
const new_values = {
'comment': question['comment'],
'answer_yn': question['answer_yn'],
'answer_star': question['answer_star'],
'answer_perc': question['answer_perc'],
'image': this.state.fileToUpload,
}
// Structure: 'model', 'function to execute in model', 'object id to be edited', 'new values in a dictionary'
await this.orm.call(
'audit.snapshot_question',
'write',
[question.id],
{'vals': new_values},
)
}
# It can be an Image field - Note that `Image` starts with a capital letter.
image = fields.Image(string="image")
# Or it can be a Binary field - Note that `Binary` starts with a capital letter.
image = fields.Binary(string="image")
def write(self, vals):
image_encoded = str(vals["image"])
try:
image_encoded = image_encoded.split(",")[1]
vals["image"] = image_encoded
except:
return super(SnapshotQuestion, self).write(vals)
return super(SnapshotQuestion, self).write(vals)
In this case the base64 encoding is done for you and the data sent to the Backend (Odoo - Python) will be a
very long string that looks something like this {'image': 'iVBORw0KGgoAAAANSUhEUgAAB18}
However, when you upload a file the hard way, you have to do the encoding first like you did in step 3 and then
the data sent to the Backend (Odoo - Python) will look something like this
{'image': 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAB0UAAAPBCAYAAACBf}
That is why there is some magic that needs to be done before super().write()
can be called. You have to get
rid of the part that reads data:image/png;base64,
and keep only the very long alphanumeric string.