Master Odoo ORM patterns: search, browse, create, write, domain filters, computed fields, and performance-safe query techniques.
54
61%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./plugins/AI-Agents-Safe-Coding-Skills/skills/odoo-orm-expert/SKILL.mdThe canonical home for this skill is odoo-orm-expert in administrakt0r/AI-Agents-Safe-Coding-Skills
This skill teaches you Odoo's Object Relational Mapper (ORM) in depth. It covers reading/writing records, building domain filters, working with relational fields, and avoiding common performance pitfalls like N+1 queries.
search(), browse(), create(), write(), or unlink() calls.@odoo-orm-expert and describe what data operation you need.# Find all confirmed sale orders for a specific customer, created this year
import datetime
start_of_year = datetime.date.today().replace(month=1, day=1).strftime('%Y-%m-%d')
orders = self.env['sale.order'].search([
('partner_id', '=', partner_id),
('state', '=', 'sale'),
('date_order', '>=', start_of_year),
], order='date_order desc', limit=50)
# Note: pass dates as 'YYYY-MM-DD' strings in domains,
# NOT as fields.Date objects — the ORM serializes them correctly.total_order_count = fields.Integer(
string='Total Orders',
compute='_compute_total_order_count',
store=True
)
@api.depends('sale_order_ids')
def _compute_total_order_count(self):
for record in self:
record.total_order_count = len(record.sale_order_ids)# ✅ GOOD: One query for all records
partners = self.env['res.partner'].search([('country_id', '=', False)])
partners.write({'country_id': self.env.ref('base.us').id})
# ❌ BAD: Triggers a separate query per record
for partner in partners:
partner.country_id = self.env.ref('base.us').idmapped(), filtered(), and sorted() on recordsets instead of Python loops.sudo() sparingly and only when you understand the security implications.search_count() over len(search(...)) when you only need a count.with_context(...) to pass context values cleanly rather than modifying self.env.context directly.search() inside a loop — this is the #1 Odoo performance killer.datetime/date objects directly into domain tuples — always stringify them as 'YYYY-MM-DD'.cr.execute() raw SQL patterns in depth — use the Odoo performance tuner skill for SQL-level optimization.models.TransientModel) or wizard patterns.fbdfd63
Canonical home
since Aug 19, 2026
Also appears in
since Aug 19, 2026
since Aug 19, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.