Sometimes we will come across situations where we will have to apply some conditions in viewing, reading, or writing fields. Odoo helps us to do the same using Attributes(attrs). Using this, we can conditionally apply attributes to fields. invisible, read-only, and required are the main 3 attributes. Using these attributes, we can hide a field based on another field, make it a non-editable field, or we can make it mandatory. We will discuss it in this blog.
For the same, we can use the example of the Student(student.student) model as given below.
class StudentRecord(models.Model):
_name = 'student.student'
include_last_name = fields.Boolean('Include Last name')
name = fields.Char(string = "Name", required = True)
last_name = fields.Char(string = "Last Name")
dob = fields.Date(string = "Date of birth")
age = fields.Integer(string = "Age")
gender = fields.Selection([
('m', 'Male'),
('f', 'Female'),
('o', 'others')],
string = "Gender", required = True)
student_blood_group = fields.Selection([
('A+', 'A+ve'),
('B+', 'B+ve'),
('O+', 'O+ve'),
('AB+', 'AB+ve')],
string = "Blood Group")
nationality = fields.Many2one('res.country', string = 'Nationality')
Form view for the same is given below.
<record id="student_studen_form" model="ir.ui.view">
<field name="name">student.student.form</field>
<field name="model">student.student</field>
<field name="arch" type="xml">
<form>
<sheet>
<group>
<group>
<field name="name"/>
<field name="include_last_name"/>
<field name="dob"/>
<field name="gender"/>
</group>
<group>
<field name="last_name"/>
<field name="age"/>
</group>
</group>
</sheet>
</form>
</field>
</record>
Invisible FIeld(attrs="{'invisible': [(condition)] }")
Now let's see how we can make a field invisible in some specific conditions. For that, let’s hide the field Last Name( last_name) based on the value given in the field Include Last name (include_last_name). So let's add attrs to the xml code of the field view.
<field name="last_name" attrs="{'invisible': [('include_last_name','=',False)] }"/>
So, the above code means that if the value of the field include_last_name is true the field last_name will be visible else it will be invisible.
There is also one more attribute called “column_invisible”, similar to the attribute “invisible.” It is used when we need to hide a field based on a field inside another object connected to the current object by an One2many connection.
<field name="total" attrs="{'column_invisible': [('parent.is_total','=',False)]}"/>
In the above example, the field total is invisible if the value of is_total is None which is a field of another object which belongs to One2many field parent.
Mandatory Fields(attrs="{‘required’: [(condition)] })
Next is mandatory fields. In Odoo, we can make a field mandatory or not mandatory depending upon another field.
Now let's see how that works. For that, let's make the field Last Name( last_name) mandatory based on the value given in the field Include Last name (include_last_name). So let's add attrs to the XML code of the field view.
<field name="last_name" attrs="{'required':[('include_last_name','=',True)]}"/>
So what this code does is that if the value of the field include_last_name is true the field last_name will be mandatory else it will not be.
ReadOnly Fields(attrs="{‘readonly’: [(condition)] }”)
The last one is Readonly which helps us to make a field read-only or writable field with respect to another field.
Now let's see how that works. For that, let's make the field Last Name( last_name) read-only based on the value given in the field Include Last name (include_last_name). So let's add attrs to the XML code of the field view.
<field name="last_name" attrs="{'readonly': [('include_last_name', '!=', True)]}"/>
So what this code does is that if the value of the field include_last_name is true the field last_name will be writable else it will be readonly.
Multiple Conditions
We can mix the attributes or apply multiple attributes for the same field
1) Same attribute with multiple conditions
<field name="last_name" attrs="{'invisible':
['|', ('include_last_name','=',False), ('name','=',False)] }"/>
This means that field last_name will be invisible if include_last_name is false or name is false. The condition '|' is used for the OR condition and for AND condition is by default so we don’t have to use any special symbol for its condition.
2) Multiple attributes with a single condition
<field name="last_name" attrs="{'readonly': [('include_last_name', '!=', True)], 'required': [('dob', '=', True)], 'invisible': [('name', '=', False)]}"/>
3) Multiple attributes with multiple conditions
<field name="last_name" attrs="{'readonly': [('include_last_name','=',False), ('name','=',False)], 'invisible': [('include_last_name','=',False), (name, '!=', True)], 'required': ['|', ('include_last_name','=',False), ('name','=',False)]}"/>
4) Multiple attributes with single and multiple conditions
<field name="last_name" attrs="{'readonly': [('include_last_name','=',False)], 'invisible': [('include_last_name','=',False)], 'required': ['|', ('include_last_name','=',False), ('name','=',False)]}"/>
And other than fields, attrs can be applied to groups, pages, buttons, div, etc.
So in Odoo, it is this simple to make a field hidden, mandatory, or read-only with respect to another field in Odoo.