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

Viewed 158

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.

1 Answers

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>
Related