Odoo ORM API
Goal
Manipulate data programmatically using the Odoo Object-Relational Mapping (ORM) API.
1. The Environment (self.env)
The environment stores the context, the cursor, and the user.
self.env.user: The current user record.
self.env.company: The current company record.
self.env.context: A dictionary containing session data (lang, timezone, etc.).
self.env.ref(xml_id): Get a record by its XML ID.
Modifying the Environment
Methods in Odoo models are executed with the current user's privileges. To change this:
2. Searching Records
search(domain, limit=None, offset=0, order=None): Returns a recordset.properties = self.env['estate.property'].search([
('state', '=', 'new'),
('expected_price', '<', 100000)
], limit=10)
search_count(domain): Returns the number of records (integer).
browse(ids): Returns a recordset from a list of IDs.property = self.env['estate.property'].browse([1, 2, 3])
- Domain: A list of tuples
(field, operator, value).
- Operators:
=, !=, >, >=, <, <=, like, ilike, in, not in.
- Logical:
& (AND, default), | (OR), ! (NOT).
3. CRUD Operations
create(vals_list): Create new records.# Single record
new_prop = self.env['estate.property'].create({'name': 'New House', 'expected_price': 50000})
# Multiple records (faster)
props = self.env['estate.property'].create([{'name': 'H1'}, {'name': 'H2'}])
write(vals): Update records.# Updates ALL records in the recordset 'properties'
properties.write({'state': 'offer_received'})
unlink(): Delete records.properties.unlink()
4. Exceptions
Use Odoo exceptions to stop execution and warn the user.
from odoo.exceptions import UserError, ValidationError
# Validations
if record.selling_price < record.expected_price * 0.9:
raise ValidationError("Selling price cannot be lower than 90% of expected price.")
# User Warnings
if not record.partner_id:
raise UserError("You must select a partner first.")
5. Mapped and Filtered
Optimization tools for recordsets.
mapped(field_name): Returns a list of values (or recordset if method returns records).prices = properties.mapped('selling_price')
partners = properties.mapped('partner_id') # Returns recordset
filtered(func_or_field): Returns a subset of records.# Filter by field boolean value
sold_props = properties.filtered('is_sold')
# Filter by lambda
expensive_props = properties.filtered(lambda p: p.expected_price > 500000)
Converted and distributed by TomeVault — claim your Tome and manage your conversions.
1---2name: odoo-orm-api3description: Master the Odoo ORM for data manipulation, environment management, and CRUD operations. Use when this capability is needed.4---56# Odoo ORM API78## Goal9Manipulate data programmatically using the Odoo Object-Relational Mapping (ORM) API.1011## 1. The Environment (`self.env`)12The environment stores the context, the cursor, and the user.13* `self.env.user`: The current user record.14* `self.env.company`: The current company record.15* `self.env.context`: A dictionary containing session data (lang, timezone, etc.).16* `self.env.ref(xml_id)`: Get a record by its XML ID.1718### Modifying the Environment19Methods in Odoo models are executed with the current user's privileges. To change this:20* `sudo()`: Switch to the Superuser (bypass security rules).21 ```python22 self.env['res.partner'].sudo().create({'name': 'Admin Contact'})23 ```24* `with_context(**kwargs)`: Add or modify context keys.25 ```python26 self.with_context(lang='fr_FR').name # Translates name to French27 ```28* `with_company(company)`: Switch the active company.2930## 2. Searching Records31* `search(domain, limit=None, offset=0, order=None)`: Returns a recordset.32 ```python33 properties = self.env['estate.property'].search([34 ('state', '=', 'new'),35 ('expected_price', '<', 100000)36 ], limit=10)37 ```38* `search_count(domain)`: Returns the number of records (integer).39* `browse(ids)`: Returns a recordset from a list of IDs.40 ```python41 property = self.env['estate.property'].browse([1, 2, 3])42 ```43* **Domain**: A list of tuples `(field, operator, value)`.44 * Operators: `=`, `!=`, `>`, `>=`, `<`, `<=`, `like`, `ilike`, `in`, `not in`.45 * Logical: `&` (AND, default), `|` (OR), `!` (NOT).4647## 3. CRUD Operations48* `create(vals_list)`: Create new records.49 ```python50 # Single record51 new_prop = self.env['estate.property'].create({'name': 'New House', 'expected_price': 50000})52 # Multiple records (faster)53 props = self.env['estate.property'].create([{'name': 'H1'}, {'name': 'H2'}])54 ```55* `write(vals)`: Update records.56 ```python57 # Updates ALL records in the recordset 'properties'58 properties.write({'state': 'offer_received'})59 ```60* `unlink()`: Delete records.61 ```python62 properties.unlink()63 ```6465## 4. Exceptions66Use Odoo exceptions to stop execution and warn the user.67```python68from odoo.exceptions import UserError, ValidationError6970# Validations71if record.selling_price < record.expected_price * 0.9:72 raise ValidationError("Selling price cannot be lower than 90% of expected price.")7374# User Warnings75if not record.partner_id:76 raise UserError("You must select a partner first.")77```7879## 5. Mapped and Filtered80Optimization tools for recordsets.81* `mapped(field_name)`: Returns a list of values (or recordset if method returns records).82 ```python83 prices = properties.mapped('selling_price')84 partners = properties.mapped('partner_id') # Returns recordset85 ```86* `filtered(func_or_field)`: Returns a subset of records.87 ```python88 # Filter by field boolean value89 sold_props = properties.filtered('is_sold')90 # Filter by lambda91 expensive_props = properties.filtered(lambda p: p.expected_price > 500000)92 ```9394---95> Converted and distributed by [TomeVault](https://tomevault.io/claim/itobetter) — claim your Tome and manage your conversions.96<!-- tomevault:4.0:skill_md:2026-04-13 -->