Web forms are like digital sheets where people can share different kinds of information, such as their contact details, requests, or responses to surveys. These forms have different kinds of fields like text fields, radio buttons, and selection fields. Now, there's a special field in these forms meant for sending documents or files—it's called the attachment field. This is where you can easily submit files like documents. Let's take a closer look at how we can add this file-submission feature to a web form, making it simple for users to share their documents with us.
Odoo features a dedicated model, 'ir.attachments,' designed for storing attachments submitted by end users. In this blog, I'll guide you through the process of utilizing the 'ir.attachments' model to enable file uploads through web forms.
We need to create a field in our model to handle attachments. So, let's create a many2many field in the res.partner model for storing attachments.
file_attachment_ids = fields.Many2many('ir.attachment', string='Attachments')
To set up the web form, we need to create an XML file. In this file, we use the 'form' tag to define the different fields we want, including the one for attaching files. The 'form' tag comes with various attributes like 'class,' 'action,' 'method,' and 'enctype.'
Now, the 'enctype' attribute is particularly important when dealing with attachments. It tells the form how to handle the characters in the file. In simple terms, it ensures that the file content is not altered or encoded in a way that could cause issues when submitting it. Think of it as a special instruction to handle files properly.
Here's an example 'form' tag with the 'enctype' attribute:
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="website_partner_form">
<t t-call="website.layout">
<div id="wrap" class="oe_structure oe_empty">
<section class="s_website_form" data-vcss="001" data-snippet="s_website_form">
<div class="container">
<form action="/form/submit" method="post" enctype="multipart/form-data">
<input type="hidden" name="csrf_token" t-att-value="request.csrf_token()"/>
<div class="col-lg-7 col-md-8">
<label class="col-md-3 col-sm-4 control-label" for="att">Attach file</label>
</div>
<div class="col-lg-7 col-md-8">
<input type="file" name="att" accept="image/*,application/pdf,video/*"/>
</div>
<button type="submit" class="btn btn-primary">Create </button>
</form>
This will create a file input field like this.
In the provided example, The 'action' attribute ("/form/submit") specifies where the form data will be sent, while the 'method' attribute ("post") ensures that this data is not visible in the URL for security reasons. The 'enctype' attribute ("multipart/form-data") is particularly crucial for handling attachments, ensuring that the file content remains intact during the submission process.
Notably, the 'csrf_token' serves as a security measure to guard against Cross-Site Request Forgery (CSRF) attacks. Within the form, a user-friendly section for attaching files is created using the 'label' and 'input' elements. The 'name' attribute ("att") is employed to identify the attached data, and the 'accept' attribute restricts file types to images, PDFs, and videos. Finally, the 'button' element initiates the form submission, commencing the process of creating and saving the submitted data.
In the controller, we need to create a function that will handle encoding the file and then saving it to the database. Below is a sample code:
@route(['/form/submit], type='http', auth='public', website=True)
def file_upload(self, redirect=None, **kw):
current_partner_id = request.env.user.partner_id
file_name = kw.get('att').filename
file = kw.get('att')
attachment_id = request.env['ir.attachment'].create({
'name': file_name,
'type': 'binary',
'datas': base64.b64encode(file.read()),
'res_model': current_partner_id._name,
'res_id': current_partner_id.id
})
current_partner_id.update({
file_attachment_ids: [(4, attachment_id.id)],
})
For attaching files to partners, simply select the desired file and click "Create." This action will add the file as an attachment to the corresponding field in the partner record.
By following these steps, it is really easy to upload files using web forms in Odoo 17. This makes things better for users and helps gather information more smoothly.