Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/odoo/documentation/llms.txt

Use this file to discover all available pages before exploring further.

Odoo’s developer framework is a full-stack toolkit for building modular business applications. Every feature in Odoo — accounting, inventory, CRM, e-commerce — is a module built on the same foundation of Python models, XML views, and a JavaScript frontend. You can extend any existing app or build an entirely new one from scratch without touching the core codebase. The framework follows a three-tier architecture: the presentation tier is built with HTML5, JavaScript (using the OWL component framework), and CSS; the business logic tier is written exclusively in Python; and the data tier uses PostgreSQL as the only supported RDBMS. Understanding this separation is the key to effective Odoo development.
Since version 15.0, Odoo actively transitions its frontend to the in-house OWL (Odoo Web Library) reactive component framework. The legacy JavaScript widget system is still supported but deprecated. New frontend work should target OWL.

The Technical Stack at a Glance

LayerTechnologyRole
PresentationHTML5, JavaScript, OWL, CSSViews, widgets, client actions
Business LogicPython 3.10+Models, ORM, controllers
TemplatingQWeb (XML)Views, reports, email templates
DataPostgreSQLPersistent storage
ConfigurationXML / CSV data filesSecurity rules, menus, demo data

What a Module Contains

An Odoo module is a Python package inside an addons directory. It can contain any combination of:
  • Business objects — Python classes extending odoo.models.Model, automatically mapped to database tables by the ORM.
  • Views — XML files defining list, form, kanban, graph, and other UI representations.
  • Data files — XML or CSV files that load configuration, security rules, and demo records.
  • Web controllers — Python classes handling HTTP requests via odoo.http.route.
  • Static assets — JavaScript, CSS, and image files served to the browser.
A minimal module requires only two files:
my_module/
├── __init__.py        # Python package marker
└── __manifest__.py    # Module metadata and dependencies

Core Framework Components

Tutorials

Hands-on exercises to build skills in Odoo development. Start with the Server Framework 101 tutorial to build a real estate module from scratch.

Setup Guide

Install Git, Python, clone the Odoo source, create a virtual environment, and run odoo-bin for the first time.

ORM API

Complete reference for models, field types, CRUD methods, domains, environment, and API decorators.

Module Manifests

Document __manifest__.py fields, module structure, data files, and the upgrade mechanism.

Actions

Window actions, server actions, report actions, URL actions, scheduled crons, and action bindings.

Security

Access rights via ir.model.access CSV, record rules with ir.rule, groups, sudo(), and field-level access.

Testing

TransactionCase, HttpCase, test tags, --test-enable, browser tours, and performance query count assertions.

Web Framework

OWL components, services, registries, QWeb templates, and building custom views in the JavaScript layer.

The ORM in One Glance

All database interaction goes through the ORM. You never write raw SQL for normal business logic. Models are declared as Python classes:
from odoo import models, fields, api

class RealEstateProperty(models.Model):
    _name = 'estate.property'
    _description = 'Real Estate Property'
    _order = 'date_availability'

    name = fields.Char(required=True)
    expected_price = fields.Float(required=True)
    state = fields.Selection(
        [('new', 'New'), ('offer_received', 'Offer Received'),
         ('sold', 'Sold'), ('cancelled', 'Cancelled')],
        default='new', required=True, copy=False,
    )
    salesperson_id = fields.Many2one('res.users', default=lambda self: self.env.user)

    @api.depends('living_area', 'garden_area')
    def _compute_total_area(self):
        for record in self:
            record.total_area = record.living_area + record.garden_area

    total_area = fields.Integer(compute='_compute_total_area')
The ORM automatically creates the estate_property table in PostgreSQL, handles migrations, enforces access rights, fires computed field recomputation, and much more.

Security Model Overview

Odoo’s security is data-driven and group-based. Access control works in two layers:
  1. Model-level access (ir.model.access) — grants or denies create/read/write/unlink on a whole model for a group.
  2. Record-level rules (ir.rule) — domain-based predicates that restrict which individual records a user can see or modify.
Both are typically declared in CSV and XML data files loaded by the module manifest.

Next Steps

If you are new to Odoo development, follow the Server Framework 101 tutorial first. It walks you from an empty directory to a fully-functional real estate application covering models, views, security, computed fields, and actions.

Build docs developers (and LLMs) love