Odoo has different types of fields like Character, Integer, Boolean, etc. Also, have the relational fields which help to create relationships between different models. A reference field will help to create a dynamic relationship in a model. Which means we can select the model dynamically to create the relation. In Many2one, One2many and Many2many fields we can pre-define the target model in which the relationship needs to be created. For example, in a Sale Order, if we create a Many2one field to Customers, it will only create a relation between these two models, here we pre-define the target model that is customers.
In the case of the reference field first, we can select the target model and then select the record. For example, In Customer model I need to add a field ‘Document Source’, In this, for some customers, I need to add a Purchase Order as document source, for some other customers need to add Sale Order as source, and also sometimes I may need to add an Invoice as the source. In this case, I can define a reference field, so I can first choose the model (Purchase, Sale, or Invoice) and then select the record.
We can see a simple example of a reference field from Settings >> Technical >> Menu Items.
If we try to create a Menu Item from here, we have to choose an Action for this menu. This Action field is a Reference Field. Because first, we have to select the action model, ie have to select whether it is an ir.actions.the report, ir.actions.server, ir.actions.act_window, etc. After selecting that, we can select the particular action of the selected model.
After selecting the model it will show another field to choose the records in the selected model.
After saving, it will show as a single field (only the record) like a Many2one field.
We can check how we can define the reference fields. For this, I’m taking the above ‘Document Source field in Contacts’ as an example.
source_document = fields.Reference(selection=[('sale.order', 'Sale Order'),
('purchase.order', 'Purchase Order'),
Here we can choose a Sale Order, Purchase Order or Invoice for customers from the same field.
Customer with Sale ref.
Customer with Purchase ref.
Customer with Invoice ref.
Also, we can choose the values for the selection from a function. Consider I have to select records from all modules in a field, then
source_document = fields.Reference(selection='_select_target_model’, string=”Source Document”)
models = self.env['ir.model'].search()
return [(model.model, model.name) for model in models]
It will show all available models to select.
A reference field will store in the database as <model_name>, id.
We can access the reference fields like we access a Many2one filed.
Now we can check how we can write data into a reference field.
For example in this ‘Source Document’ field, I want the Last Sale Order of the customer as reference,
model = self.env['ir.model'].search([('model', '=', 'sale.order')])
return [(model.model, model.name)]
source_document = fields.Reference(selection='_selection_target_model',
order = self.env['sale.order'].search([('partner_id', '=', self.id)], order='id desc',
for rec in self:
rec.source_document = '%s,%s' % ('sale.order', order.id)
rec.source_document = False
order = self.env['sale.order'].search([('partner_id', '=', self.id)], order='id
for rec in self:
order.id = rec.source_document.id
In the above code, it will select the last sale order of the partner if he has an order,
defining an ‘inverse’ function to make the compute field editable, so we can also select the orders.
We can write data in to a reference field like ,
self.field_name = '%s,%s' % ('model.name', id)
Eg : self.order_ref = '%s,%s' % (purchase.order', order.id)