with one click
odoo-orm-expert
Master Odoo ORM patterns: search, browse, create, write, domain filters, computed fields, and performance-safe query techniques.
Menu
Master Odoo ORM patterns: search, browse, create, write, domain filters, computed fields, and performance-safe query techniques.
Use when CrossFrame Suite routes explicit Chinese casebook work: turning materials into reusable cases, anonymized entries, mechanisms, and retrieval indexes.
Use only when the user explicitly names crossframe-critical for a Chinese structural critique dossier, article plan, or long-form critical essay.
Use when CrossFrame Suite routes explicit Chinese proposition testing, debate analysis, hidden-premise review, rebuttal design, or withdrawal condition checks.
Use when CrossFrame Suite routes explicit Chinese reader replies, editor responses, consultation-style short answers, or boundary-aware structural advice.
Use when explicit CrossFrame work needs a Chinese critical insight essay, commentary, concept essay, public piece, or structure-to-article draft after diagnosis.
Use when CrossFrame Suite routes explicit Chinese notes for books, theories, articles, excerpts, bidirectional reading, absorption, or conflict mapping.
| name | odoo-orm-expert |
| description | Master Odoo ORM patterns: search, browse, create, write, domain filters, computed fields, and performance-safe query techniques. |
| risk | safe |
| source | self |
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').id
mapped(), 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.