There are many web forms that we have been using for different purposes, such as submitting some details like contact information, requests for something, submitting surveys, etc. We can see different fields in these web forms such as text fields, radio buttons, selection fields, etc. The field used for attaching a document or file is one among them. Let's check out how to make an attachment field in the web form to get files or documents from the end users.
Odoo has a model ‘ir.attachments’ for storing attachments from the end users. So in this blog, I am going to explain how we can use the ‘ir.attachments’ model for uploading files from web forms.
I will show an example of how to use ir.attachments for uploading files.
At first, I created a many2many field in ir.attachments model having relation with res.partner.
class Attachment(models.Model):
_inherit = 'ir.attachment'
attach_rel = fields.Many2many('res.partner', 'attachment', 'attachment_id', 'document_id', string = "Attachment")
And inherited the res.partner model and added a field to store the attachments.
class ResPartner(models.Model): _inherit='res.partner'
attachment=fields.Many2many('ir.attachment', 'attach_rel', 'doc_id', 'attach_id', string="Attachment", help='You can
upload your document', copy=False)
So let’s create a view for our web-form. In the XML file, you need to add the form tag and add the fields you want to see in the form. The input field for attachment can be added anywhere you like. I just added some fields in the example below, including the attachment field. You can add this field inside the form tag. The form tab has a number of attributes like class, action, method, enctype, etc. The attribute enctype has an important role in the case of attachments. It is used if the input is a file and it says that the characters in the file will not be encoded.
Here is an example of a form tag with an enctype attribute.
<form action="" method="post" enctype="multipart/form-data" class="oe_import">
Next, you have to create a view for this attachment field inside the form. Here is an example of the code.
<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" multiple="true" accept="image/*,application/pdf,video/*"/>
</div>
In the controller, you have to write a function to encode the file and save it to the database like the below:
@route(['/my/account'], type='http', auth='public', website=True)
def file_upload(self, redirect=None, **post):
<-- your code here-->
partner_id = request.env.user.partner_id
Attachment = request.env['ir.attachment']
file_name = post.get('attachment').filename
file = post.get('attachment')
attachment_id = Attachment.create({
'name': file_name,
'type': 'binary',
'datas': base64.b64encode(file.read()),
'res_model': partner_id._name,
'res_id': partner_id.id
})
partner_id.update({
'attachment': [(4, attachment_id.id)],
})
<-- your code here-->
base64.b64encode(file.read()) will encode the uploaded file content. The content of the file will be read until it reaches an empty string, and it returns the encoded data plus a trailing newline character(‘\n’).
Now the file is stored in the database; this is how you can upload files from web forms.