How to customize field definitions by group in Odoo view

In everyday business cases, there are a lot of situations where a particular field needs to have different attributes or attribute values based on different access groups.

This type of case is possible to handle in Odoo, however, there are two different solutions based on which version of Odoo is used.

In Odoo 15 and older versions, this can be achieved by adding a more generic definition of the field in the main view, while the one specific for certain groups is added in a new inherited view, which is limited only to the specific access group.

For example, a very simple case can be if the field phone​ in the Leads view by default needs to be readonly​, but only for group Sales Administrator is editable:

<record id="crm_lead_view_form" model="https://ir.ui.view">
<field name="name">https://crm.lead.form</field>
<field name="model">crm.lead</field>
<field name="arch" type="xml">
<form>
​​...
<field name='phone' readonly="True"/>
</form>
</field>
</record>

<record id="crm_lead_view_phone_form" model="https://ir.ui.view">
<field name="model">crm.lead</field>
<field name="inherit_id" ref="crm.crm_lead_view_form"/>
<field name="priority">99</field>
<field name="groups_id" eval="[(6, 0, [ref('sales_team.group_sale_manager')])]"/>
<field name="arch" type="xml">
<form>
<field name='phone' position="attributes">
<attribute name="readonly">False</attribute>
</field>
</form>
</field>
</record>

Starting from Odoo 16 this type of inherited view with an attached group to it is no longer supported, and will show a server error if used. The new approach now is by defining the same field twice in the view with different access group rules.

The same example with the phone​ field in Odoo 16 would look like the following:

<record id="crm_lead_view_form" model="ir.ui.view">
    <field name="name">crm.lead.form</field>
    <field name="model">crm.lead</field>
    <field name="arch" type="xml">
        <form>
            ...
            <field name='phone' groups="!sales_team.group_sale_manager" readonly="True"/>
            <field name='phone' groups="sales_team.group_sale_manager" readonly="False"/>
        </form>
    </field>
</record>

To avoid any confusion, this example does not intend to show the best solution on how to make a field editable only for certain access groups, but it is just used to demonstrate how to define the same field with different attributes for different groups.