Understanding the Rare ORM Method name_get() in Odoo 19
When working with Odoo development, most developers frequently use ORM methods like create(), write(), search(), and unlink(). However, Odoo also provides several lesser-known ORM methods that quietly power many UI behaviors behind the scenes.
One such important method is name_get().
Even though many developers rarely touch it, this method becomes extremely important when dropdown labels, breadcrumbs, chatter references, or Many2one fields start displaying incorrect or confusing values.
What is name_get() in Odoo?
The name_get() method defines how a record should appear as a readable label inside the Odoo interface.
Odoo uses it in places like:
Many2one dropdowns
Breadcrumbs
Chatter mentions
Smart buttons
Search popups
RPC calls and backend references
The method returns a list of tuples in this format:
[(record_id, display_name)]
Example:
[(1, 'Azure Interior'),
(2, 'Deco Addict'),
(3, 'Agrolait')]
Default Behavior of name_get()
If you do not override name_get(), Odoo automatically uses the field defined in _rec_name.
By default, _rec_name is usually the name field.
Internally, Odoo behaves roughly like this:
def name_get(self):
result = []
name_field = self._rec_name or 'name'
for record in self:
result.append((record.id, record[name_field] or ''))
return result
So if your model only contains a name field, the dropdown simply shows that value.
While this works for simple cases, real business applications often require more descriptive labels.
Major Change in Odoo 19 – display_name Becomes Important
Starting from Odoo 17 and fully adopted in Odoo 19, the web client no longer directly relies on name_get() for Many2one dropdown labels.
Instead, Odoo now primarily uses the display_name field.
This is a very important architectural change.
What This Means
Simply overriding name_get() is no longer enough in Odoo 19.
To properly customize record labels, you should:
Create a computed
display_namefieldUse
@api.depends()correctlyKeep
name_get()for backward compatibility
This ensures compatibility with:
Older RPC integrations
Reports
Shell scripts
Legacy custom modules
Recommended Pattern in Odoo 19
from odoo import models, fields, api
class HospitalWard(models.Model):
_name = 'hospital.ward'
_description = 'Hospital Ward'
_rec_name = 'name'
name = fields.Char(required=True)
code = fields.Char()
capacity = fields.Integer()
display_name = fields.Char(
compute='_compute_display_name',
store=False,
)
@api.depends('name', 'code', 'capacity')
def _compute_display_name(self):
for record in self:
name = record.name or ''
if record.code:
name = f'[{record.code}] {name}'
if record.capacity:
name = f'{name} (Cap: {record.capacity})'
record.display_name = name
# Backward compatibility
def name_get(self):
return [
(record.id, record.display_name)
for record in self
]
Example Output
Instead of showing:
Cardiology
Neurology
the dropdown will now display:
[W-01] Cardiology (Cap: 20)
[W-02] Neurology (Cap: 15)
This greatly improves usability, especially in large ERP systems where similar names may exist across departments or branches.
Why display_name is Better in Odoo 19
Using display_name provides several advantages:
Reactive UI updates
Better frontend performance
Cleaner web client integration
Improved consistency across views
Modern Odoo architecture compatibility
In Odoo 19, display_name is effectively the primary display mechanism.
name_get() and name_search() Should Always Work Together
A common mistake developers make is customizing the label using name_get() but forgetting to update search behavior.
For example:
If the dropdown label is:
[PAT-001] John Smith
but search only checks the name field, searching for PAT-001 will fail.
That is why name_search() should usually be overridden together with name_get().
Proper name_search() Example
@api.model
def name_search(
self,
name='',
domain=None,
operator='ilike',
limit=100
):
domain = domain or []
if name:
records = self.search(
['|',
('patient_code', operator, name),
('name', operator, name)] + domain,
limit=limit
)
return records.name_get()
return super().name_search(
name=name,
domain=domain,
operator=operator,
limit=limit
)
Important Note for Odoo 19
In Odoo 19:
domain
is used instead of:
args
Using args may raise a TypeError in newer versions.
Final Thoughts
For many years, name_get() was the standard approach for customizing record labels in Odoo.
However, Odoo 19 changes the game by shifting most UI rendering responsibility to display_name.
The modern best practice is:
Use computed
display_nameAdd proper
@api.dependsKeep
name_get()for compatibilityPair it with
name_search()
These small improvements make your custom modules feel much more polished, user-friendly, and production-ready.
Understanding these lesser-known ORM methods is what separates basic Odoo development from advanced enterprise-level implementation.

Comments
Post a Comment