Search code examples
templatescontrollerodooodoo-12

attachments are not being saved on backend from website odoo 12


I want to add attachment while edit a form named my information on website and i want to save the attachment on the backend. I have added input field in the form for attachment but while saving the form i am not getting the attachment in the backend. Here is my code:-

template file:-

<div class="form-group row">
     <div class="col-lg-3 col-md-4">
      <label class="control-label" for="Attachments">
       Attach Files
      </label>
     </div>
     <div class="col-lg-7 col-md-12">
       <input id='attachment' type="file"
       class="form-control o_website_form_input"
       name="attachment" multiple="true"
       data-show-preview="true"                                                                          
       accept="application/pdf"/>
      </div>
</div>

controller file:-

@route(['/path/to/template'], type='http', auth='public', website=True)
def account(self, redirect=None, **post):
    values = self._prepare_portal_layout_values()
    User = request.env.user
    partner = User.partner_id
    
    if post:

        print("post::::::::::::::::::::::", post, values)
        attachment_ids = []
        attachment_list = request.httprequest.files.getlist('attachment')
        print("attachment_list::::::::::::::::", attachment_list)
        for att in attachment_list:
            if post.get('attachment'):
                attachments = {
                    'res_name': att.filename,
                    'res_model': 'res.partner',
                    'res_id': partner.sudo().id,
                    'datas': base64.encodestring(att.read()),
                    'type': 'binary',
                    'datas_fname': att.filename,
                    'name': att.filename,
                }
                attachment_obj = http.request.env['ir.attachment']
                att_record = attachment_obj.sudo().create(attachments)
                attachment_ids.append(att_record.id)
        if attachment_ids:
            values.update({'attachment_ids': [(6, 0, attachment_ids)]})

So Can anyone give me some idea what i am missing?


Solution

  • The enctype attribute specifies the content type used to submit the form to the server (when the value of the method is post). The default value for this attribute is application/x-www-form-urlencoded.

    The value multipart/form-data should be used in combination with the INPUT element, type="file".

    You need to set enctype to multipart/form-data to use input of type file.

    You can find an example in the web_editor module:

    <form class="form-inline"
                method="POST"
                action="/web_editor/attachment/add"
                enctype="multipart/form-data"
    

    The input of type file is defined as following:

    <input type="file" class="d-none" name="upload" t-att-accept="widget.accept" multiple="multiple"/>
    

    The files are recovered from the request object (like you did):

    request.httprequest.files.getlist('upload')
    

    Edit:

    enctype

    The content type application/x-www-form-urlencoded is inefficient for sending large quantities of binary data or text containing non-ASCII characters. The content type multipart/form-data should be used for submitting forms that contain files, non-ASCII data, and binary data.

    multiple = boolean

    Indicates whether the user is to be allowed to specify more than one value.

    In HTML, you can simply use the minimized form multiple but in Odoo template, Odoo will raise an XMLSyntaxError:

    XMLSyntaxError: Specification mandates value for attribute multiple  
    

    Boolean attributes may legally take a single value: the name of the attribute itself (e.g., multiple="multiple").

    Their appearance in the start tag of an element implies that the value of the attribute is true. Their absence implies a value of false

    Setting the value of multiple attribute to multiple or ``true` will give you the same result.