Search code examples
odooodoo-14

How to add a field for File Attachment in Sign-up page?


I just did a customization in a website sign-up page by following this odoo 14: how i can add additional fields in SignUp like address etc.

I can now do most of the fields I want because most of them are in type text.

However, I need one more field that must be receiving a file attachment. (Users can upload a file attachment, be it documents/pdfs/images, upon registration.

The question is how do I achieve such task? I know I need to have a field for it somewhere in the database and its related model like res.partner, but I don't know how to embed a field to upload file attachment and send to the server and store it in the database altogether.


Solution

  • You want to send a file through a POST so you need first to set the enctype form attribute to multipart/form-data.

    Example:

    <template id="signup" inherit_id="auth_signup.signup" name="Sign up login">
        <xpath expr="//form" position="attributes">
            <attribute name="enctype">multipart/form-data</attribute>
        </xpath>
    </template>
    

    Alter the auth_signup.fields template and add an input of type file

    Example:

    <template id="signup_fields" inherit_id="auth_signup.fields" name="Auth Signup attachment form field">
        <xpath expr="//div[last()]" position="after">
            <div class="form-group field-login">
                <label for="attachment">Attachment</label>
                <input type="file" name="attachment" id="attachment" class="form-control form-control-sm"/>
            </div>
        </xpath>
    </template>
    

    Then override _signup_with_values method to prepare the field values before saving to database.

    Example:

    import base64
    
    class AuthSignupStreet(AuthSignupHome):
        def _signup_with_values(self, token, values):
            context = self.get_auth_signup_qcontext()
            attachment = context.get('attachment')
            if attachment:
                datas = base64.b64encode(attachment.read())
                values.update({'attachment': datas, 'attachment_name': attachment.filename})
            super(AuthSignupStreet, self)._signup_with_values(token, values)
    

    After that, inherit the res.partner model to add 2 fields for attachment and attachment_name.

    Example:

    class ResPartnerInherit(models.Model):
        _inherit = 'res.partner'
    
        attachment = fields.Binary(string="Attachment", attachment=True)
        attachment_name = fields.Char(string='Attachment Name')
    

    Finally, (optional) inherit the form in Contact so that it displays (and also allows edit) the attachment.

    Example:

    <record id="res_partner_form_attachment" model="ir.ui.view">
        <field name="name">res.partner.form.attachment</field>
        <field name="model">res.partner</field>
        <field name="inherit_id" ref="base.view_partner_form"/>
        <field name="arch" type="xml">
            <xpath expr="//form/sheet/notebook" position="inside">
                <page string="Attachment">
                    <field name="attachment" filename="attachment_name"/>
                    <field name="attachment_name" invisible="1"/>
                </page>
            </xpath>
        </field>
    </record>