Odoo 18 Development Book: Traversing Through Record

A record set is a collection of related items or records. When working with a single record or a record set of length 1, accessing any field value is straightforward. However, when dealing with multiple records, you cannot directly access a field value by simply using the field name. If you attempt to use the dot notation (e.g., self.partner_id.name) on a record set containing more than one record, an error will occur.

For example, consider the res.partner model, which holds all the contact records in an Odoo database. If the variable partner contains a single res.partner record, you can easily access the contact's name using partner.name. However, if partner contains multiple records, direct field access like this is not possible.

In such cases, Odoo provides the mapped() method, which allows you to efficiently traverse and access field values across a record set containing multiple records.

Let’s go through an example to understand this process in detail.

from odoo import fields, models

class StudentStudent(models.Model):
   _name = "student.student"
   _description = "Student"

   name = fields.Char(string="Name", required=True)
   phone = fields.Char(string="Phone Number")
   email = fields.Char(string="Email")
   partner_id = fields.Many2one('res.partner', string="Partner", required=True)
   date = fields.Date(string="Date", default=fields.Date.today())
   parent_id = fields.Many2one('student.parent', string="Parent")
from odoo import fields, models

class StudentParent(models.Model):
    _name = "student.parent"
    _description = "Parent"

    name = fields.Char(string="Name", required=True)
    phone = fields.Char(string="Phone Number")
    email = fields.Char(string="Email")
    partner_id = fields.Many2one('res.partner', string="Partner", required=True)
    date = fields.Date(string="Date", default=fields.Date.today())
    student_ids = fields.Many2many('student.student', string="Students")

The Parent model includes a relational field called student_ids, which stores all students associated with that parent. If the student_ids field contains a single student record, you can directly access the student's name using student_ids.name. However, if student_ids contains multiple student records, direct access in this way is not possible.

To retrieve the names of all associated students, we can define a method called get_student_name(). In this method, the mapped() function can be used to efficiently extract all student names from the student.student recordset.

def _get_students_name(self, parents):
    names = parents.mapped('student_ids.name')

In this scenario, the mapped(path) method iterates over the fields of a recordset, where path is a string representing the field name, and nested fields can be accessed using dot notation. The mapped() method returns either a new recordset or a list containing all the values that correspond to the specified path for each record in the current recordset.

At each level of the provided path, mapped() builds an intermediate recordset. For example, when using student_ids.name, the mapped() method first retrieves all student_ids and then collects the name field from each related student record.

In this case, the variable names will store a Python list of all student names.

  • When the path points to a relational field, mapped() returns a recordset.
  • When the path refers to a basic field type (such as Char, Integer, etc.), mapped() returns a Python list of values.

Although mapped() is a powerful and convenient method, it is not always the most performance-efficient choice. This is because it operates in memory within the Odoo server and may trigger multiple SQL queries when traversing relational fields. In such cases, it is generally better to use the search() method with an appropriate domain to optimize query performance.

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message