Custom field doesn't respect access rights

Viewed 353

I have created a new field (signature image) to be shown in the My Profile section by inheriting the (res.users) module.

_inherit = 'res.users'
signature_image = fields.Binary()

Now, the user can change everything in the profile section (including the image and time zone, etc.) but can't change the new field.

The user gets a permission error message.

You are not allowed to modify 'Users' (res.users) records.

This operation is allowed for the following groups:

  • Administration/Access Rights

Why this new field is not following the access rules of the module and doesn't behave like the other fields?

1 Answers

That really seems weird, but is default behaviour for many versions now.

When adding new fields to model res.users you have to add those fields to a special attribute of the class behind it.

You can find examples in modules hr or sale_stock.

For Odoo 14 or some earlier versions you have to override the class' __init__ and add your fields to the special attribute(s), like this

class Users(models.Model):
    _inherit = ['res.users']

    property_warehouse_id = fields.Many2one('stock.warehouse', string='Default Warehouse', company_dependent=True, check_company=True)

    def __init__(self, pool, cr):
        """ Override of __init__ to add access rights.
            Access rights are disabled by default, but allowed
            on some specific fields defined in self.SELF_{READ/WRITE}ABLE_FIELDS.
        """

        sale_stock_writeable_fields = [
            'property_warehouse_id',
        ]

        init_res = super().__init__(pool, cr)
        # duplicate list to avoid modifying the original reference
        type(self).SELF_READABLE_FIELDS = type(self).SELF_READABLE_FIELDS + sale_stock_writeable_fields
        type(self).SELF_WRITEABLE_FIELDS = type(self).SELF_WRITEABLE_FIELDS + sale_stock_writeable_fields
        return init_res

In Odoo 15 everything was changed to python properties. But you can find new examples on the same modules, like this:

class Users(models.Model):
    _inherit = ['res.users']

    property_warehouse_id = fields.Many2one('stock.warehouse', string='Default Warehouse', company_dependent=True, check_company=True)

    @property
    def SELF_READABLE_FIELDS(self):
        return super().SELF_READABLE_FIELDS + ['property_warehouse_id']

    @property
    def SELF_WRITEABLE_FIELDS(self):
        return super().SELF_WRITEABLE_FIELDS + ['property_warehouse_id']
Related