- Module structure and manifest
- ORM: models, fields, and relations
- Computed fields and constraints
- View types and inheritance
- Security: access rights and record rules
- Controllers and QWeb
Module Structure Questions
FAQ
It declares the module's metadata — name, version, author, description — and its dependencies (depends), data files to load (data), and asset files (assets). Odoo reads this file to determine load order and whether dependencies are satisfied before installing the module.
data files are always loaded — on install and on upgrade. They contain production data like security rules, menus, and views. demo files are loaded only when the database is created with demo data enabled; they contain sample records for learning and testing purposes.
It means the record is loaded only on the first install and never updated on subsequent upgrades — even if the XML changes. Use it for default data that users are expected to customize (e.g., a default email template). Without it, every upgrade would overwrite user modifications.
ORM and Model Questions
Classical (extension): _inherit = 'existing.model' without _name — extends the existing model in-place, adding fields and methods. Prototype (copy): _inherit = 'existing.model' with a new _name — creates a new model that copies the parent's structure. Delegation: _inherits = {'parent.model': 'field_id'} — the child stores parent fields by reference via a Many2one, with field access delegated transparently.
Many2one: many records point to one parent (FK column in the child table). One2many: the inverse of Many2one — no column in the parent, the child has the FK. Many2many: many-to-many via a join table. Many2one stores a value; One2many is a virtual field; Many2many creates an intermediate table.
Use store=True when: the field is read frequently, the computation is expensive, or you need to search/filter on the field. The value is computed on write and stored in a DB column. Use non-stored (default) when: the field is rarely read, it's purely for UI display, or the computation is trivial. Non-stored fields recompute on every read.
@api.constrains('field1', 'field2') runs Python code on write — use for complex cross-field validations. It runs in memory and can call the ORM. _sql_constraints creates a PostgreSQL constraint (UNIQUE, CHECK) — enforced at the database level, faster, applies even on direct SQL writes, but limited to what SQL supports.
sudo() returns a recordset with superuser privileges — it bypasses access rights and record rules. Use it when: you need to read/write records that the current user doesn't have access to by design (e.g., portal users creating records). Never use sudo() without first validating that the current user has the right to trigger that action.
Security Questions
ir.model.access.csv controls model-level permissions: which groups can create/read/write/delete records of a model at all. ir.rule controls row-level access: which specific records a user can see, filtered by a domain. Access rights are checked first; if they pass, record rules apply.
Global rules (no group assigned) apply to everyone — they are AND-combined with any group-specific rules. Group-specific rules apply only to members of the specified group — multiple group rules for the same model are OR-combined for a user who belongs to multiple groups. This design lets you expand access for admins by adding an allow-all group rule.
View and QWeb Questions
A view with inherit_id extends the parent view. XPath expressions locate elements in the parent; the position attribute controls how the new content is inserted: before, after, inside (append children), replace, or attributes (modify existing attributes). Multiple modules can inherit the same view — Odoo applies them in sequence based on module load order.
t-field renders an Odoo model field with widget formatting (dates, currencies, m2o names) and enables inline editing in the website editor. t-out renders a Python expression as raw HTML — use for fields.Html content. t-esc renders a Python expression as escaped plain text — safe for user-supplied strings.
- Be able to write a model with all field types from memory
- Know the three inheritance types and when to use each
- Understand the security layers: groups → access rights → record rules
- Be ready to explain stored vs non-stored computed fields with examples

