Introduction
If you have spent time working inside the Odoo data model, you have probably come across situations where you need to display a value from a linked record directly on a form, without asking the user to click through to another model. The Related field is how Odoo solves this in a clean, declarative way.
Rather than writing a computed field with a Python method, a Related field simply reads through an existing relational chain and exposes the value at the end of it. It is one of the most useful tools in the Odoo developer guide, and it is also accessible to business consultants working with Odoo Studio who need to surface contextual information without writing code.
This guide explains what the Related field stores, how it works in the Odoo framework, how to create and configure it through Studio or Python, and where it fits into real business workflows.
What is the Related Field in Odoo
In the Odoo ORM, a Related field is not a distinct field type in the same way Float or Char are. Instead, it is a shortcut that exposes a field from another model by following a chain of relational fields. The Related field takes on the type of whatever field it points to at the end of the chain.
The simplest example: a sale order has a partner_id field (a Many2one pointing to res.partner). A Related field defined as related='partner_id.country_id' would expose the customer country directly on the sale order, without storing a separate copy of it.
From the user perspective, a Related field looks exactly like any other field in the form view. If the terminal field in the chain is a Char, the Related field renders as a text input. If it is a Many2one, it renders as a dropdown. If it is a Boolean, it shows a checkbox. The Related field inherits the visual presentation of the field it mirrors.
By default, Related fields are read-only and not stored in the database. This means they always show the current value from the source record, but you cannot filter or search records using them directly in a domain unless you set store=True.
In Odoo Studio, the Related field is available when adding a new field to a form. You select an existing relational path, and Studio creates the field with the appropriate configuration. This makes it one of the more practical Odoo Studio fields for consultants who need to enrich forms without writing any Python.
How the Field Works
When Odoo reads a Related field, it follows the chain of field names separated by dots. Each step in the chain (except the last) must be a relational field: a Many2one, One2many, or Many2many. The last field in the chain can be any type.
Here is a straightforward example of a Related field defined in a Python module:
from odoo import fields, models
class SaleOrder(models.Model):
_inherit = 'sale.order'
partner_country_id = fields.Many2one(
related='partner_id.country_id',
string='Customer Country',
store=True,
)
In this example, Odoo follows partner_id to reach the res.partner record, then reads country_id from it. The result is a Many2one field on the sale order that mirrors the customer country.
Stored vs. Unstored Related Fields
This is the most important distinction to understand. By default, a Related field has store=False, meaning it is computed on the fly every time the record is read. The value does not live in the database table for the model.
With store=True, Odoo writes the value to the database column when the source record changes. This enables filtering, grouping, and searching on the Related field, which makes it far more useful for reports and list views.
The trade-off is that stored Related fields consume database space and require an update trigger whenever the source changes. Odoo handles this automatically through its dependency tracking system, but it is worth being aware of for performance-sensitive models with many records.
Read-Only vs. Writable Related Fields
By default, Related fields are read-only. Adding readonly=False makes the field editable. When a user changes the value, Odoo writes it back through the chain to the source record. This is a powerful but potentially surprising behavior: editing the Related field on a sale order actually modifies the partner record, not the order itself.
Only use writable Related fields when you genuinely intend this write-through behavior. It can be very useful in some contexts, such as a quick-edit field on a list view, but it can also lead to unintended data changes if users do not understand what they are editing.
Key Field Attributes
These are the main parameters you configure on a Related field:
- related: The dot-separated chain of field names (e.g.,
'partner_id.country_id'). This is the only required attribute. - store: Set to
Trueto persist the value in the database. Enables filtering and grouping. - readonly: Set to
Falseto allow users to edit the field, which writes through to the source. - string: The label displayed to users. Defaults to the label of the terminal field.
- depends: Normally not needed since Odoo infers dependencies from the
relatedchain automatically. Only needed in edge cases.
How It Interacts with the Odoo ORM
Reading a Related field returns the value of the terminal field on the linked record. If any link in the chain is empty (for example, partner_id is not set), the Related field returns False. This is standard Odoo ORM behavior and applies to all relational fields in the Odoo data model.
Related fields are fully supported in domains, views, and reports when stored. Unstored Related fields can be displayed in form and list views, but they cannot be used as filter criteria in a search domain unless the server evaluates them in Python rather than SQL.
Business Use Cases
Related fields appear across nearly every part of an Odoo implementation. Here are five practical examples from real business workflows.
CRM and Sales: Customer Phone on Sale Orders
A common request from sales teams is to see the customer phone number directly on the sale order form, without having to open the customer record separately. A Related field defined as related='partner_id.phone' on sale.order solves this immediately. It surfaces the phone number in context, speeds up sales calls, and requires zero extra development effort. In Odoo Studio, a consultant can add this in under a minute using the Related field option.
Accounting: Company Currency on Invoice Lines
In multi-company Odoo setups, accountants sometimes need to display the company currency directly on invoice lines for reporting clarity. A Related field like related='move_id.company_id.currency_id' chains through two Many2one fields to reach the currency. This three-level chain is valid, though keeping chains short is generally recommended for performance reasons. Storing this field enables filtering invoices by company currency in analytical reports.
Inventory: Product Category on Stock Move Lines
Warehouse teams managing stock moves often need to see the product category without opening each product record. A Related field on stock.move.line pointing to product_id.categ_id exposes the category directly on the move line. With store=True, this enables grouping incoming and outgoing stock by product category in the Inventory reporting views, which is particularly useful for businesses managing a wide range of product families.
Manufacturing: Internal Reference on Work Order Components
Production managers in manufacturing companies frequently need to see the internal product reference on work order component lines during production. A Related field reading product_id.default_code on mrp.workorder lines puts the reference number exactly where the operator needs it, reducing errors caused by selecting similar products. This kind of small customization has a real impact on production floor accuracy.
Timesheets and Projects: Employee Department
When project managers review timesheet lines, they sometimes need to see which department the employee belongs to for cost allocation purposes. A Related field defined as related='employee_id.department_id' on account.analytic.line (the timesheet model) displays the department directly on the timesheet entry. Stored with store=True, it allows filtering timesheets by department in project analysis reports, making Odoo a more complete project management and resource allocation tool.
Creating or Customizing the Related Field
There are three main ways to add a Related field to an Odoo model, depending on your technical context and how the deployment is managed.
Using Odoo Studio (No Code)
Odoo Studio lets you add Related fields without writing any Python. Here is how to do it:
- Open Odoo Studio from the main menu.
- Navigate to the form where you want to add the field.
- Click Add a field and choose Related Field.
- Select the relational path by clicking through the available fields step by step.
- Give the field a label and configure whether it should be stored or read-only.
- Save and close Studio.
Studio automatically creates the field with an x_studio_ prefix and places it in the view. This is one of the most efficient ways to use Odoo Studio fields for adding contextual information to existing forms. No database changes are needed on your side.
Using Python in a Custom Module
For developers working on Odoo customization through code, Related fields are defined in the model class. This is the approach recommended by the Odoo developer guide for any changes that need version control and multi-environment deployment:
from odoo import fields, models
class StockMoveLine(models.Model):
_inherit = 'stock.move.line'
product_category_id = fields.Many2one(
related='product_id.categ_id',
string='Product Category',
store=True,
)
After defining the field, add it to the relevant view XML so it appears in the interface. Odoo handles the database column creation automatically during module installation or upgrade. This is the standard Odoo development approach for reliable, maintainable Odoo customization.
Using the XML-RPC API
For deployments managed programmatically, for example through a remote configuration notebook, Related fields can be created via the XML-RPC API by setting the related attribute on the field definition:
field_id = models.execute_kw(
ODOO_DB, uid, ODOO_API_KEY,
'ir.model.fields', 'create',
[{
'name': 'x_partner_country_id',
'field_description': 'Customer Country',
'model_id': sale_order_model_id,
'ttype': 'many2one',
'relation': 'res.country',
'related': 'partner_id.country_id',
'store': True,
'readonly': True,
'state': 'manual',
}]
)
When creating a Related field via the API, you need to specify the correct ttype and relation manually, as the API does not automatically infer the type from the chain the way the Python ORM does. This is the approach Dasolo uses for deploying Odoo field customizations remotely through automated configuration scripts.
Best Practices
1. Store the field when filtering or grouping is needed
If users need to filter a list view by the Related field, or group records by it in a pivot table, add store=True. Without it, database-level filtering is not possible, and Odoo would have to load all records in Python to apply the filter, which does not scale. For display-only fields in form views, unstored is perfectly fine.
2. Keep the chain as short as possible
A two-level chain like partner_id.country_id is clean and performant. A four-level chain like picking_id.sale_id.partner_id.country_id introduces more potential failure points and is harder to maintain. If you find yourself building very deep chains, consider whether a computed field with explicit Python logic would be clearer and easier to debug.
3. Understand what readonly=False actually means
A writable Related field does not create a local copy of the data. It modifies the source record. If you make partner_id.phone editable on a sale order, changing it updates the partner record in res.partner. That change affects every other document linked to that partner. Make sure this is intentional, and always inform users when a field edits a shared record.
4. Use Related fields for display, not for data duplication
Related fields are meant to surface existing data in context, not to duplicate it. If you find yourself wanting to have an independent copy of a value that can diverge from the source, a regular field with a default set by an onchange or automated action is the right approach, not a Related field with store=True and readonly=False.
5. Check access rights implications
A Related field reads through to another model. If the current user does not have read access to that model, the field may return an empty value silently. This is correct Odoo security behavior, but it can confuse users who see a blank field without understanding why. When designing forms with Related fields, verify that the expected user roles have read access to all models in the chain.
Common Pitfalls
Filtering on an unstored Related field
This is the most common mistake. A developer or consultant adds a Related field to a list view and then tries to add a search filter on it. If store=False (the default), Odoo cannot filter by this field at the database level. The domain will either raise an error or silently return no results. Always add store=True to any Related field you plan to use in search filters or group-by clauses.
Unexpected write-through behavior
Setting readonly=False on a Related field and then being surprised that edits affect the source record is a very common issue, especially when Related fields are added through Odoo Studio by users unfamiliar with the mechanics. Before making a Related field editable, always confirm with the business stakeholders whether they want edits to propagate back to the source model.
Not handling empty intermediate fields
If any field in the chain is empty, the Related field returns False. In a form view, this usually means the field shows blank. In a computed field or a Python method that reads the Related field value, you need to handle the False case to avoid TypeErrors. This is easy to overlook in testing when all records happen to have complete data, but it surfaces in production when optional fields are left empty.
Using Related where a Computed field is more appropriate
Related fields work well when you are mirroring a single field through a relational chain. When you need to apply any logic, transformation, or conditional behavior on the value, a Computed field with a Python method is the right choice. Trying to do conditional logic through a Related field chain leads to workarounds that are hard to maintain and easy to break in future Odoo upgrades. This is a common point in any Odoo technical tutorial on field types.
Performance issues with many stored Related fields on large models
Every stored Related field requires an update when the source value changes. If you add ten stored Related fields on a model with hundreds of thousands of records, and the source fields update frequently, you can create significant database write load. For large-scale Odoo development, profile the performance impact of stored Related fields and prefer unstored display-only fields where real-time accuracy is not critical.
Conclusion
The Related field is one of the most practical tools available in the Odoo framework for surfacing contextual information without duplicating data. It lets you read through relational chains, display values from linked records directly in any view, and optionally store those values for filtering and reporting.
Understanding when to use store=True, when readonly=False is appropriate, and how to handle empty intermediate fields will save you time and prevent the most common data issues in Odoo implementations. Whether you are a developer writing Python modules, a consultant using Odoo Studio, or a technical lead managing remote configurations, the Related field is worth knowing well.
If you are building or extending an Odoo data model, Related fields belong in your toolkit alongside Computed fields, Many2one fields, and the other Odoo field types covered in this series.
At Dasolo, we help companies implement, customize, and optimize Odoo across Sales, Operations, Accounting, and beyond. If you need help designing your Odoo data model, adding custom fields to your workflows, or extending your Odoo setup with reliable, maintainable code, we are here to help. Reach out to us and let us discuss how we can support your Odoo project.