Complete AI Training
Sign inBecome a member

Your job's AI kit

Get your AI kit

Tell us who you are and what you do. We show you your kit right away and email you the link: skills, prompts, AI agents, MCP servers and courses for your job.

500+ jobs ready, and we make a kit for any other job. No payment needed to look.

Share

Skill · Business

Odoo orm expert

Master Odoo ORM patterns: search, browse, create, write, domain filters, computed fields, and performance-safe query techniques.

Agentic Awesome SkillsAdded Sep 5, 2026
Use it in my AI

How to use it

  1. Start your plan and connect your AI once
  2. Add the skill to your AI, one time only: press Copy skill and paste it into your AI's instructions: a project in ChatGPT, Claude or Grok, a Gem in Gemini, an agent in Microsoft 365 Copilot, or a rule in Cursor. It stays there for every new chat. In Kimi, paste it at the start of a new chat.
  3. Ask for the task in your own words, or say it directly:
Use the Odoo orm expert skill to help me with this.
SKILL.md

Odoo ORM Expert

Overview

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.

When to Use This Skill

  • Writing search(), browse(), create(), write(), or unlink() calls.
  • Building complex domain filters for views or server actions.
  • Implementing computed, stored, and related fields.
  • Debugging slow queries or optimizing bulk operations.

How It Works

  1. Activate: Mention @odoo-orm-expert and describe what data operation you need.
  2. Get Code: Receive correct, idiomatic Odoo ORM code with explanations.
  3. Optimize: Ask for performance review on existing ORM code.

Examples

Example 1: Search with Domain Filters

# 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.

Example 2: Computed Field

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)

Example 3: Safe Bulk Write (avoid N+1)

# ✅ 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').id

Best Practices

  • ✅ Do: Use mapped(), filtered(), and sorted() on recordsets instead of Python loops.
  • ✅ Do: Use sudo() sparingly and only when you understand the security implications.
  • ✅ Do: Prefer search_count() over len(search(...)) when you only need a count.
  • ✅ Do: Use with_context(...) to pass context values cleanly rather than modifying self.env.context directly.
  • ❌ Don't: Call search() inside a loop — this is the #1 Odoo performance killer.
  • ❌ Don't: Use raw SQL unless absolutely necessary; use ORM for all standard operations.
  • ❌ Don't: Pass Python datetime/date objects directly into domain tuples — always stringify them as 'YYYY-MM-DD'.

Limitations

  • Does not cover cr.execute() raw SQL patterns in depth — use the Odoo performance tuner skill for SQL-level optimization.
  • Stored computed fields can cause significant write overhead at scale; this skill does not cover partitioning strategies.
  • Does not cover transient models (models.TransientModel) or wizard patterns.
  • ORM behavior can differ slightly between Odoo SaaS and On-Premise due to config overrides.