20 -Â Custom Record Names & Searching (Goodbye name_get, Hello display_name)
Welcome back! When you click on a Many2one dropdown in Odoo, what do you see? Usually, you just see the basic name of the record.
But what if you have two employees named "John Smith"? How do you know which one to pick? Ideally, you want the dropdown to show something much more helpful, like [EMP-001] John Smith (Engineering).
In older versions of Odoo (v16 and below), developers used a complicated, clunky method called name_get to do this. In Odoo 19, the core team threw that old method in the trash and replaced it with a modern, elegant solution: _compute_display_name.
Let's learn how to customize exactly how your records look, and how users search for them!
1. Customizing the Display Name (_compute_display_name)
Every model in Odoo has a hidden, automatic computed field called display_name. Whenever Odoo needs to show a record in a Many2one dropdown, at the top of a form view, or in a breadcrumb trail, it calls the _compute_display_name function to figure out what text to show.
By overriding this function, we can combine multiple fields into a beautiful, readable string.
Real-World Scenario: Let's create a custom "Course" model. Instead of just showing the course title, we want it to clearly show the course code and the title together.
from odoo import models, fields, api
class TrainingCourse(models.Model):
_name = 'training.course'
_description = 'Training Course'
code = fields.Char(string='Course Code', required=True)
name = fields.Char(string='Course Title', required=True)
instructor_id = fields.Many2one('res.users', string='Instructor')
# We override the core display name compute method!
@api.depends('code', 'name')
def _compute_display_name(self):
for record in self:
# If both code and name exist, combine them cleanly.
if record.code and record.name:
record.display_name = f"[{record.code}] {record.name}"
else:
# Always provide a fallback just in case the code is missing!
record.display_name = record.name or 'New Course'
Now, anywhere in your entire Odoo 19 system where a user selects a course, they will see exactly what you formatted!
2. The Easy Way to Search (_rec_names_search)
Customizing the name is great, but it creates a new problem. If your dropdown says [PY-101] Python Basics, what happens if the user searches by typing the instructor's name into the dropdown box?
By default, Odoo only searches the standard name field. It will say "No records found."
Odoo 19 gives us a brilliant, one-line shortcut to fix this. It is a model attribute called _rec_names_search. You simply give it a Python list of all the fields Odoo should check when a user types into a search box.
class TrainingCourse(models.Model):
_name = 'training.course'
_description = 'Training Course'
# Tell Odoo to search these three fields automatically!
_rec_names_search = ['name', 'code', 'instructor_id.name']
code = fields.Char(string='Course Code')
name = fields.Char(string='Course Title')
instructor_id = fields.Many2one('res.users', string='Instructor')
With just that one line, a user can type "John" into the Course dropdown, and Odoo will instantly find all courses taught by an instructor named John!
3. Advanced Searching (_search_display_name)
Sometimes, _rec_names_search isn't quite powerful enough. What if you want to write complex Python logic to filter searches based on the current user's permissions, or force a highly specific database query?
For advanced scenarios, you can override the _search_display_name method. This method catches the exact string the user typed and allows you to build a custom search domain (a list of SQL-like filters) to hand back to the database.
@api.model
def _search_display_name(self, operator, value):
# 'value' is the exact string the user typed into the search box
# 'operator' is usually 'ilike' (which means "contains")
# 1. Create a custom search domain matching against code OR name
domain = ['|', ('code', operator, value), ('name', operator, value)]
# 2. Add extra logic! For example, only search through 'active' courses
domain = [('state', '=', 'active')] + domain
# 3. Return the domain back to Odoo to execute the actual database search
return domain
đŸ’¡ Developer Pro-Tips for Odoo 19
Don't Google Old Tutorials: If you read older Odoo tutorials or forum posts, you will see name_get() everywhere. Do not use it! In Odoo 19, name_get is dead. Always use _compute_display_name.
Performance Matters: Because _compute_display_name is triggered constantly across the system (in list views, Kanban views, and dropdowns), keep the code inside it incredibly fast. Avoid doing complex database search() queries inside this method, or your entire Odoo system will lag.
The _rec_name Attribute: If you don't want to combine multiple fields, but you just want Odoo to use a completely different field as the default name (like using a serial_number field instead of name), you don't need to write a compute function at all! Just add _rec_name = 'serial_number' to the top of your model class right under _description.
Homework for this lesson: Create a library.book model. Use _compute_display_name to make the books show up as "Title by Author". Then, use _rec_names_search so users can search for the book by typing either the Title or the ISBN number!
There are no comments for now.