Prerequisites at a Glance
| Prerequisite | Why Odoo needs it | Status |
|---|---|---|
| Python OOP (classes, inheritance) | Every Odoo model is a Python class | ✅ Fully covered |
| Python Decorators | @api.depends, @api.onchange, @api.constrains are decorators |
✅ Fully covered |
| Python List Comprehensions | Used constantly in domain filters and computed field logic | ✅ Fully covered |
| SQL Basics (SELECT, JOIN) | Domain filters compile to SQL; understanding helps debugging | ✅ Fully covered |
| XML Basics | All Odoo views and data files are XML | ✅ Fully covered |
| OWL JS (for frontend work) | Odoo 19 frontend is built on OWL — client actions, widgets, POS | ✅ Fully covered |
| HTML Basics | Portal and Website templates use HTML/QWeb | ✅ Fully covered |
| CSS Basics | Styling portal/website pages | ✅ Fully covered |
| HTTP Basics (GET/POST) | Portal and Website controllers handle HTTP requests | ✅ Covered (intermediate) |
Python: How Much Do You Need?
Python is the non-negotiable prerequisite. Odoo's backend is Python code from top to bottom. Here's what you need specifically:
- OOP is essential — every model is a class that inherits from
models.Model. You need to understandself, class attributes, instance methods, and inheritance. - Decorators from day one —
@api.depends,@api.onchange,@api.constrains,@api.model. If you don't understand decorators, you won't understand why Odoo methods are structured the way they are. - Exceptions —
raise ValidationError("...")is the standard way to block invalid data in Odoo. - String, datetime, dict operations — used constantly in computed field logic and data transformations.
from odoo import models, fields, api
from odoo.exceptions import ValidationError
class LibraryBook(models.Model):
_name = 'library.book'
_description = 'Library Book'
name = fields.Char(required=True)
price = fields.Float()
discount = fields.Float()
final_price = fields.Float(compute='_compute_final_price', store=True)
@api.depends('price', 'discount')
def _compute_final_price(self):
for record in self:
record.final_price = record.price * (1 - record.discount / 100)
@api.constrains('price')
def _check_price(self):
for record in self:
if record.price < 0:
raise ValidationError("Price cannot be negative.")
This single example uses: class inheritance, class attributes, decorators (@api.depends, @api.constrains), a for loop over self (a recordset), instance attribute assignment, and exception raising. All of these Python concepts appear in your first module.
XML: What You Need
Odoo views, menus, actions, security records, email templates, and website pages are all written in XML. You need to understand:
- Element attributes:
<field name="foo" string="Bar" required="1"/> - Nesting and parent-child relationships
- Self-closing tags:
<field name="x"/> - Escaping:
&,<,>
Odoo's XML uses a template engine called QWeb which adds directives: t-if, t-foreach, t-field, t-esc. These are used in website pages and PDF report templates. The HTML course on ylearner covers XML syntax directly — the concepts transfer to Odoo's XML without any gaps.
SQL: How Much?
You write Odoo domains (Python lists that compile to SQL WHERE clauses) — not raw SQL. A domain like [('state', '=', 'sale'), ('partner_id.country_id.code', '=', 'US')] becomes a SQL WHERE clause with a JOIN automatically.
However, understanding SQL helps you:
- Write efficient domains (understanding JOINs helps you avoid N+1 patterns)
- Debug slow queries using PostgreSQL's
EXPLAIN ANALYZE - Write advanced reports using raw SQL with
self.env.cr.execute()
The SQL course on ylearner covers everything you need for Odoo development.
OWL JS: When Do You Need It?
OWL is Odoo's JavaScript UI framework. How much you need depends on what you're building:
- Backend-only modules (models, views, wizards, reports): OWL is optional — you write Python and XML only.
- Client actions, custom field widgets, dashboards: OWL is required — you write JavaScript components.
- POS screens: OWL is required — POS is an OWL single-page application.
- Portal/Website development: OWL is NOT needed — you use QWeb templates and standard JavaScript.
Start with Python, then build your first backend module (no OWL needed). Once comfortable with backend development, add OWL for client-side work. The OWL JS course on ylearner covers everything you need.
Quick Self-Assessment
If you can answer these questions, you're ready to start the Odoo module development section:
| Question | Covered in |
|---|---|
What does class LibraryBook(models.Model): inherit from? | Python OOP |
What does @api.depends('price', 'discount') do? | Python Decorators |
What is [('state', '=', 'sale')] syntax? | Python lists + Odoo domain syntax |
What SQL does SELECT * FROM sale_order WHERE state = 'sale' look like as an Odoo domain? | SQL + ORM concepts |
What does t-foreach do in a QWeb template? | XML/QWeb basics |
📋 Summary
- Python OOP and decorators are non-negotiable — they appear in every Odoo model from day one.
- XML basics transfer directly from HTML knowledge — same concepts, different content.
- SQL understanding helps write efficient domains and debug slow queries, but you don't write raw SQL for standard operations.
- OWL JS is only required for frontend-heavy work (client actions, widgets, POS) — not for backend module development.
- The recommended order: Python → SQL basics → build backend modules → add OWL for frontend work.
FAQ
For backend modules (models, views, wizards, reports): no JavaScript required. For client actions, custom field widgets, and POS screens: yes — specifically OWL JS. If your goal is backend Odoo development, you can get productive without JavaScript. Add OWL JS later when you need to build frontend components.
You need: OOP (classes, inheritance, self), decorators, and basic data structures (lists, dicts). Intermediate Python — functions, exceptions, string formatting, list comprehensions — is the realistic minimum. If you need to build that foundation first, the Python course on ylearner covers everything you need through OOP and beyond.
Odoo abstracts SQL through its ORM. Basic SQL knowledge (SELECT, WHERE, JOIN) helps you understand how domains work and debug slow queries, but you rarely write raw SQL for standard operations. For advanced optimisation and custom reports, you will use self.env.cr.execute() — for those cases, the SQL course has you covered.
You can follow tutorials and make small changes to existing views and code. But you will hit a wall when you need to write computed fields with decorators, understand model inheritance, or debug ORM queries. Invest in Python OOP and decorators first — it makes everything else click immediately.