We are well-versed in Odoo and understand how relational fields are used to establish connections between different models. To populate these relational fields, we often need to search for and locate the specific values from a comprehensive list of available records. Odoo's name search function facilitates this search process, providing a convenient way to customize the search based on our specific needs.
This blog will delve into the name search function and explore its various use cases in depth.
The name search function in Odoo 16 is employed to search for records within a model that are linked through a relational field. This search can be conducted using a partial value or with fields other than the default "name" field of the record. By default, in a Many2one field, you can search and select records by typing their names. However, if you wish to search using different parameters or criteria, you can leverage the name_search function to achieve this level of customization.
Let's look at an Odoo example. When entering a customer's name in the Customer field of a new sale order quotation or invoice, a search from previous records can be performed.
Additionally, searching that specific record is possible when we type in the contact's email ID as seen in the example below.
You may also notice that we are able to search using a partial email address or name. To obtain this property, use the name search function.
Here is a look at the definition of the name search function.
@api.model
def _name_search(self, name, args=None, operator='ilike', limit=100, name_get_uid=None):
# code
return self._search(expression.AND([domain, args]), limit=limit, access_rights_uid=name_get_uid)
* name (str) - The pattern to match the name.
* args (list) - An optional domain for searching to indicate additional restrictions.
* operator (str): Domain operator for names that match, like "like," "ilike," "=," and so forth
* Limit (int): This option allows you to specify how many records will be returned at most.
* name_get_uid - Either to restrict users or to specify the user.
Suppose we need to include a phone number in sale order to look for the consumers. To do that, we must inherit the model and define a name search function in the "res.partner."
class ResPartner(models.Model):
_inherit = 'res.partner'
@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100, name_get_uid=None):
args = list(args or [])
if name:
args += ['|', '|', ('name', operator, name), ('email', operator, name),
('phone', operator, name)]
return self._search(args, limit=limit, access_rights_uid=name_get_uid)
The default value for 'args' is set to None. To customize the conditions for the name search function, we can specify a domain and incorporate the 'args' list within the function.
Now, it is possible to search contacts using the phone number as well.
You can offer multiple options within the domain and utilize the dot ('.') operator for Many2one fields.
For example, if you wish to include the option to search using the state name, you can access it by invoking the dot operator on the Many2one field 'state_id' as 'state_id.name'. Consequently, the 'args' list would be as follows:
args += ['|', '|', '|', ('name', operator, name), ('phone', operator, name), ('email', operator, name), ('state_id.name', operator, name)]
Let's explore another example of the name search function in the 'res.city' model.The 'res.city' employs a name_get function that incorporates the zip code into its display name. Consequently, when a Many2one field is associated with this model and a search is initiated, a list featuring its enhanced display name, inclusive of the zip code, is displayed.
class ResCity(models.Model):
_name = 'res.city'
_description = 'City'
_order = 'name'
name = fields.Char(string="Name", help='Name of city', required=True,
translate=True)
zipcode = fields.Char(string="Zip", help='Zip of city')
country_id = fields.Many2one('res.country', string='Country',
help='Country to which the city belongs to',
required=True)
state_id = fields.Many2one('res.country.state', string='State',
help='State to which the city belongs to',
domain="[('country_id', '=', country_id)]")
def name_get(self):
res = []
for city in self:
name = city.name if not city.zipcode else '%s (%s)' % (
city.name, city.zipcode)
res.append((city.id, name))
return res
@api.model
def _name_search(self, name='', args=None, operator='ilike', limit=100,
name_get_uid=None):
args = list(args or [])
if not (name == '' and operator == 'ilike'):
args += ['|', (self._rec_name, operator, name),
('zipcode', operator, name)]
return self._search(args, limit=limit, access_rights_uid=name_get_uid)
However, searching among the records using the zip code is enabled by the name_search function defined in the model. You can also observe that in the name_search function, we utilized 'self._rec_name' and implemented an 'if' condition to optimize the default criterion of 'ilike' with an empty string, which matches everything.
Indeed, similarly, we can customize and define the name_search function in Odoo to facilitate the search for specific records based on field values in a relational field.
To read more about adding a search menu in the customer portal Odoo 16, refer to our blog How to Add Search Menu in Customer Portal Odoo 16