This complete Odoo tutorial covers 112 topics — from installation and custom modules to ORM, views, security, QWeb, APIs, business apps, and a final complete custom Odoo module.
Course roadmap
- Introduction to Odoo
- What is Odoo?
- Odoo Features and Architecture
- Odoo Community vs Enterprise
- Odoo Installation
- Setting Up Odoo Development Environment
- Odoo Project Structure
- Odoo Configuration
- Odoo Database Management
- Odoo User and Company Setup
- Odoo Apps and Modules
- Creating Your First Odoo Module
- Odoo Module Structure
- Odoo Manifest File
- Models in Odoo
- Model Fields in Odoo
- Char, Text and Integer Fields in Odoo
- Float and Monetary Fields in Odoo
- Boolean and Selection Fields in Odoo
- Date and Datetime Fields in Odoo
- Many2one Fields in Odoo
- One2many Fields in Odoo
- Many2many Fields in Odoo
- Computed Fields in Odoo
- Related Fields in Odoo
- Default Values in Odoo
- Field Constraints in Odoo
- ORM in Odoo
- CRUD Operations in Odoo
- Create Records in Odoo
- Search Records in Odoo
- Update Records in Odoo
- Delete Records in Odoo
- Recordsets in Odoo
- Domains and Search Filters in Odoo
- Environment and Context in Odoo
- Access Rights in Odoo
- Security Groups in Odoo
- Access Control Lists (ACL) in Odoo
- Record Rules in Odoo
- XML Views in Odoo
- Form Views in Odoo
- List Views in Odoo
- Kanban Views in Odoo
- Search Views in Odoo
- Calendar Views in Odoo
- Graph Views in Odoo
- Pivot Views in Odoo
- Tree/List View Customization in Odoo
- XML Inheritance in Odoo
- View XPath in Odoo
- Odoo Menus
- Window Actions in Odoo
- Server Actions in Odoo
- Wizards in Odoo
- Transient Models in Odoo
- Buttons and Smart Buttons in Odoo
- Onchange Methods in Odoo
- Computed Methods in Odoo
- Constraints and Validation in Odoo
- Python Decorators in Odoo
- @api.model in Odoo
- @api.depends in Odoo
- @api.onchange in Odoo
- @api.constrains in Odoo
- QWeb Templates in Odoo
- Odoo Website Development
- Odoo Website Builder
- Odoo Portal
- Odoo Email Templates
- Automated Emails in Odoo
- Scheduled Actions / Cron Jobs in Odoo
- Reports in Odoo
- QWeb PDF Reports in Odoo
- Excel Reports in Odoo
- Odoo REST API
- XML-RPC API in Odoo
- JSON-RPC API in Odoo
- External API Integration in Odoo
- Webhooks Integration in Odoo
- JavaScript in Odoo
- OWL Framework in Odoo
- OWL Components in Odoo
- Odoo Frontend Development
- Odoo Backend Customization
- Custom Dashboard Development in Odoo
- Odoo Accounting Module
- Odoo Sales Module
- Odoo Purchase Module
- Odoo Inventory Module
- Odoo CRM Module
- Odoo Manufacturing Module
- Odoo HR Module
- Odoo Project Management
- Odoo Website and E-commerce
- Payment Gateway Integration in Odoo
- Shipping Integration in Odoo
- Third-Party API Integration in Odoo
- Odoo Data Import
- Odoo Data Export
- Database Migration in Odoo
- Odoo Module Upgrade
- Odoo Debugging
- Odoo Logging
- Odoo Performance Optimization
- Odoo Security Best Practices
- Git and Odoo Development Workflow
- Odoo Module Testing
- Odoo Deployment
- Odoo Interview Questions
- Real-World Odoo Development Project
- Final Project – Complete Custom Odoo Module
1. Introduction to Odoo
Odoo is an open-source business application suite and development framework. This series covers Community setup, custom modules, models/fields, XML views, security, QWeb, website/portal, APIs, standard business apps, and a complete custom Odoo module as the final project.
- Set up Odoo and a custom addons path.
- Build models, views, and security.
- Ship the final custom Odoo module.
Learning path
Install + project structure
Modules, models, fields, ORM
Views, menus, actions, security
QWeb, website, reports, cron
JS/OWL + business apps
APIs, deploy, final custom module
2. What is Odoo?
Odoo ships apps (Sales, Accounting, Inventory, etc.) and lets developers extend them with modules.
Odoo at a glance
ERP + CRM + eCommerce apps
Python backend
PostgreSQL database
XML views + QWeb
Modular addons architecture
3. Odoo Features and Architecture
Requests hit the web layer; business logic lives in models; data sits in PostgreSQL.
Architecture layers
Web / RPC (JSON-RPC, XML-RPC)
ORM + models
PostgreSQL
Addons modules
Assets (JS/CSS/OWL)
QWeb templates & reports
4. Odoo Community vs Enterprise
Community covers core ERP development; Enterprise adds studio, extra apps, and support options.
Compare tip
Community → free, open modules
Enterprise → paid apps + features
Custom modules work on both (license-aware)
Pick edition by budget and required apps
5. Odoo Installation
Official docs recommend a system user, PostgreSQL, Python deps, and a service/systemd unit for production.
- Install PostgreSQL and Python dependencies.
- Configure odoo.conf.
- Start Odoo and create a database.
Install checklist
PostgreSQL running
Python venv + requirements
odoo-bin / odoo package
Config file (odoo.conf)
Create database from UI
6. Setting Up Odoo Development Environment
Use a dedicated addons folder for your custom modules outside core Odoo.
Dev tips
addons_path = core,enterprise?,custom
--dev=all for assets/xml reload
Log level info/debug
Git ignore filestore & sessions
7. Odoo Project Structure
Keep custom code in your own addons repo; never edit upstream modules directly.
Structure
odoo/
addons/ (core)
custom_addons/
my_module/
odoo.conf
filestore/
8. Odoo Configuration
Never commit production admin passwords; use secrets and restricted file permissions.
odoo.conf sketch
[options]
admin_passwd = CHANGE_ME
db_host = localhost
db_user = odoo
db_password = odoo
addons_path = /opt/odoo/addons,/opt/odoo/custom_addons
http_port = 8069
9. Odoo Database Management
Backups include PostgreSQL dump plus filestore when attachments matter.
DB ops tip
Create DB from /web/database/manager
Backup before upgrades
Restore dump + filestore
Use separate DBs per project
10. Odoo User and Company Setup
Assign users to groups early; company settings drive accounting and documents.
Setup checklist
Company data & currency
Users + groups
Languages/timezone
Multi-company rules if needed
11. Odoo Apps and Modules
Activate Developer Mode to see technical names and update apps list.
Apps tip
Apps menu → Install
Update Apps List after adding modules
Upgrade module after code changes
Dependencies in manifest
12. Creating Your First Odoo Module
Add the module to addons_path, update apps list, then install it.
- Create module folder and manifest.
- Add a simple model + list/form view.
- Install from Apps.
Minimal module
my_library/
__init__.py
__manifest__.py
models/
views/
security/
13. Odoo Module Structure
Import Python packages in __init__.py; load XML in manifest data/demo lists.
Typical folders
models/
views/
security/
data/
wizards/
controllers/
static/src/
report/
14. Odoo Manifest File
Version, depends, and data order matter for install/upgrade success.
Manifest sketch
{
'name': 'My Library',
'version': '1.0.0',
'category': 'Services',
'depends': ['base', 'mail'],
'data': [
'security/ir.model.access.csv',
'views/book_views.xml',
],
'installable': True,
'application': True,
}
15. Models in Odoo
_name creates a new model; _inherit extends existing ones.
Model sketch
from odoo import models, fields
class LibraryBook(models.Model):
_name = 'library.book'
_description = 'Library Book'
name = fields.Char(required=True)
16. Model Fields in Odoo
Field types map to PostgreSQL columns (or relations) and drive form widgets.
Field idea
Scalar fields (Char, Integer…)
Relational (Many2one…)
Computed / related
Attributes: required, index, tracking
17. Char, Text and Integer Fields in Odoo
Char supports size/translate; Text is unbounded multi-line content.
Examples
name = fields.Char(string='Title', required=True)
notes = fields.Text()
pages = fields.Integer()
18. Float and Monetary Fields in Odoo
Monetary fields pair with res.currency for correct display and rounding.
Monetary tip
currency_id = fields.Many2one('res.currency')
amount = fields.Monetary(currency_field='currency_id')
19. Boolean and Selection Fields in Odoo
Selection values are stored as keys; labels are for UI.
Selection
active = fields.Boolean(default=True)
state = fields.Selection([
('draft', 'Draft'),
('done', 'Done'),
], default='draft')
20. Date and Datetime Fields in Odoo
UI converts Datetime to user timezone; be careful in server-side comparisons.
Date fields
publish_date = fields.Date()
due_at = fields.Datetime()
21. Many2one Fields in Odoo
Use ondelete and domain to keep relations clean and filtered.
Many2one
partner_id = fields.Many2one('res.partner', string='Customer', ondelete='restrict')
22. One2many Fields in Odoo
One2many is virtual; the inverse Many2one stores the relation.
One2many
line_ids = fields.One2many('sale.order.line', 'order_id', string='Lines')
23. Many2many Fields in Odoo
Optional relation/column names customize the junction table.
Many2many
tag_ids = fields.Many2many('library.tag', string='Tags')
24. Computed Fields in Odoo
Set store=True when you need search/group on computed values.
Computed
total = fields.Float(compute='_compute_total', store=True)
@api.depends('line_ids.price')
def _compute_total(self):
for rec in self:
rec.total = sum(rec.line_ids.mapped('price'))
25. Related Fields in Odoo
Related fields can be stored; they still depend on the path staying valid.
Related
partner_email = fields.Char(related='partner_id.email', store=True)
26. Default Values in Odoo
Callables receive the model and can use env/context for dynamic defaults.
Default
state = fields.Selection(..., default='draft')
user_id = fields.Many2one('res.users', default=lambda self: self.env.user)
27. Field Constraints in Odoo
Combine SQL constraints with Python @api.constrains for business rules.
SQL constraint
_sql_constraints = [
('isbn_uniq', 'unique(isbn)', 'ISBN must be unique!'),
]
28. ORM in Odoo
Prefer ORM over raw SQL except for justified performance cases.
ORM idea
env['model.name']
create / search / browse
write / unlink
mapped / filtered / sorted
29. CRUD Operations in Odoo
Always check access rights; sudo() is for trusted system logic only.
CRUD overview
create(vals)
search(domain) / browse(ids)
write(vals)
unlink()
30. Create Records in Odoo
Override create to set defaults or related side effects carefully.
create
book = self.env['library.book'].create({
'name': 'Odoo Guide',
'pages': 200,
})
31. Search Records in Odoo
Use domains, limit/offset/order for efficient queries.
search
books = self.env['library.book'].search([
('active', '=', True),
], limit=20, order='name')
32. Update Records in Odoo
write applies to all records in the set — filter first when needed.
write
books.write({'state': 'done'})
33. Delete Records in Odoo
Prefer archiving (active=False) for business documents when audit matters.
unlink
books.unlink()
34. Recordsets in Odoo
Recordsets are the core ORM unit — methods usually operate on self as a set.
Recordset helpers
names = books.mapped('name')
active = books.filtered('active')
book = books.ensure_one()
35. Domains and Search Filters in Odoo
Domains appear in search(), fields, actions, and record rules.
Domain example
[('state', '=', 'draft'), ('partner_id', '!=', False)]
36. Environment and Context in Odoo
Pass context with with_context(); switch company/user carefully with with_company/with_user.
env tip
self.env.user
self.env.company
self.with_context(lang='en_US').name
37. Access Rights in Odoo
Without ACL rows, users (except admin patterns) cannot access the model.
ACL idea
ir.model.access.csv
group → model → read/write/create/unlink
Install security before views that need it
38. Security Groups in Odoo
Nest implied_ids so Manager inherits User rights.
Group tip
<record id="group_library_user" model="res.groups">
<field name="name">Library User</field>
</record>
39. Access Control Lists (ACL) in Odoo
One line per group/model combination with boolean CRUD flags.
ACL CSV sketch
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
access_library_book_user,library.book.user,model_library_book,group_library_user,1,1,1,0
40. Record Rules in Odoo
Use for multi-company and “own documents only” patterns.
Record rule tip
Domain on records
global vs group rules
multi-company company_id domains
Test with non-admin users
41. XML Views in Odoo
Views bind to a model and are selected by priority/mode.
View idea
form / list / kanban / search
calendar / graph / pivot
inherit existing views
bind via actions
42. Form Views in Odoo
Use widgets and invisible/readonly attrs for better UX.
Form sketch
<form>
<sheet>
<group>
<field name="name"/>
<field name="partner_id"/>
</group>
</sheet>
</form>
43. List Views in Odoo
Enable multi-edit and optional fields where useful.
List sketch
<list>
<field name="name"/>
<field name="state"/>
</list>
44. Kanban Views in Odoo
Great for CRM stages and visual workflows.
Kanban tip
kanban-box template
group_by stage
quick create
progress bars optional
45. Search Views in Odoo
Search views power saved filters and facets.
Search sketch
<search>
<field name="name"/>
<filter string="Draft" name="draft" domain="[('state','=','draft')]"/>
<group expand="0" string="Group By">
<filter string="Status" name="groupby_state" context="{'group_by': 'state'}"/>
</group>
</search>
46. Calendar Views in Odoo
Map start/stop colors and attendees as needed.
Calendar tip
date_start / date_stop
color field
mode month/week/day
47. Graph Views in Odoo
Combine with search group_by for analytics.
Graph tip
<graph type="bar">
<field name="partner_id" type="row"/>
<field name="amount" type="measure"/>
</graph>
48. Pivot Views in Odoo
Users can rearrange rows/columns interactively.
Pivot tip
row / col / measure fields
Export analysis
Good for sales/accounting aggregates
49. Tree/List View Customization in Odoo
Use decoration-danger/info based on field expressions.
Decoration tip
<list decoration-danger="state == 'cancelled'">
<field name="name"/>
<field name="state"/>
</list>
50. XML Inheritance in Odoo
Inheritance keeps upgrades smoother when core views change.
Inherit tip
<field name="inherit_id" ref="sale.view_order_form"/>
<field name="arch" type="xml">
<!-- xpath modifications -->
</field>
51. View XPath in Odoo
Be precise — fragile xpaths break on upstream view changes.
XPath example
<xpath expr="//field[@name='partner_id']" position="after">
<field name="x_custom_note"/>
</xpath>
52. Odoo Menus
Hide menus with groups for role-based navigation.
Menu sketch
<menuitem id="menu_library_root" name="Library" sequence="10"/>
<menuitem id="menu_library_books" name="Books" parent="menu_library_root" action="action_library_book"/>
53. Window Actions in Odoo
Set domain, context, and view_mode for the action.
Action sketch
<record id="action_library_book" model="ir.actions.act_window">
<field name="name">Books</field>
<field name="res_model">library.book</field>
<field name="view_mode">list,form</field>
</record>
54. Server Actions in Odoo
Useful for bulk actions and automated record updates.
Server action tip
ir.actions.server
code / object_write / multi
Bind to Action menu
Use with base.automation
55. Wizards in Odoo
Wizards collect input then apply logic to target records.
Wizard tip
TransientModel
form view in dialog
button type=object
unlink old transient rows via vacuum
56. Transient Models in Odoo
Do not use TransientModel for persistent business documents.
TransientModel
class BookWizard(models.TransientModel):
_name = 'library.book.wizard'
name = fields.Char()
57. Buttons and Smart Buttons in Odoo
Smart buttons show counts and open related action windows.
Button tip
<button name="action_confirm" type="object" string="Confirm" class="btn-primary"/>
<button type="object" class="oe_stat_button" icon="fa-book" name="action_view_loans">
<field name="loan_count" widget="statinfo" string="Loans"/>
</button>
58. Onchange Methods in Odoo
Onchange is UI-oriented; do not rely on it for server-side security.
onchange
@api.onchange('partner_id')
def _onchange_partner_id(self):
if self.partner_id:
self.email = self.partner_id.email
59. Computed Methods in Odoo
Always declare dependencies; avoid N+1 queries inside computes.
Compute tip
@api.depends(...)
loop recordsets
prefetch related fields
store when searchable
60. Constraints and Validation in Odoo
Fail early with clear messages users can act on.
constrains
from odoo.exceptions import ValidationError
@api.constrains('pages')
def _check_pages(self):
for rec in self:
if rec.pages < 0:
raise ValidationError('Pages cannot be negative.')
61. Python Decorators in Odoo
Common ones: model, depends, onchange, constrains, returns.
Decorators list
@api.model
@api.depends
@api.onchange
@api.constrains
@api.returns (less common day-to-day)
62. @api.model in Odoo
Typical for helpers called without browsing specific records.
@api.model
@api.model
def default_get(self, fields_list):
res = super().default_get(fields_list)
res['state'] = 'draft'
return res
63. @api.depends in Odoo
Include relational paths like line_ids.price when needed.
@api.depends
@api.depends('line_ids.price', 'line_ids.qty')
def _compute_total(self):
...
64. @api.onchange in Odoo
Return warnings/domains dicts for richer UX.
@api.onchange tip
UI only — not a security gate
Can return {'warning': {...}, 'domain': {...}}
Keep logic light
65. @api.constrains in Odoo
Raise ValidationError for user-facing constraint failures.
@api.constrains tip
Fires on create/write of listed fields
Not a substitute for ACL
Clear error messages
66. QWeb Templates in Odoo
Used for website pages, reports, and some client templates.
QWeb tip
<t t-foreach="docs" t-as="doc">
<p t-esc="doc.name"/>
</t>
67. Odoo Website Development
Depends on website module; respect public vs logged-in access.
Website tip
controllers → routes
QWeb templates
snippets / themes
website.page records
68. Odoo Website Builder
Custom modules can add snippets and theme options for editors.
Builder tip
Drag-drop building blocks
Theme customize
SEO page settings
Translate website content
69. Odoo Portal
Portal ACLs differ from internal users — test with portal accounts.
Portal tip
portal group users
portal templates
share sales/invoices securely
signature / payment flows
70. Odoo Email Templates
Bind templates to models for Send message / Send email actions.
Email template tip
mail.template
model_id binding
subject + body_html
dynamic fields ${object.name}
71. Automated Emails in Odoo
Configure outgoing mail server before testing delivery.
Automation tip
Automated Actions
mail activity / notifications
outgoing mail server
avoid spam: clear opt-out & content
72. Scheduled Actions / Cron Jobs in Odoo
Keep cron methods idempotent and efficient; log failures.
Cron tip
<record id="ir_cron_library_cleanup" model="ir.cron">
<field name="name">Library Cleanup</field>
<field name="model_id" ref="model_library_book"/>
<field name="state">code</field>
<field name="code">model.action_cron_cleanup()</field>
<field name="interval_number">1</field>
<field name="interval_type">days</field>
</record>
73. Reports in Odoo
QWeb PDF is the standard approach for invoices and custom docs.
Reports tip
ir.actions.report
QWeb PDF templates
paper format
print menu binding
74. QWeb PDF Reports in Odoo
Use company header/footer and t-foreach over docs.
PDF report tip
report_type qweb-pdf
template + external layout
wkhtmltopdf / report engine deps
test with sample records
75. Excel Reports in Odoo
Useful for accounting extracts and operational spreadsheets.
Excel tip
xlsx writer libraries / report_xlsx patterns
Stream large exports
Match columns to user needs
76. Odoo REST API
Community often uses JSON-RPC; custom REST controllers are common for external apps.
REST tip
Custom http Controllers
auth=user/public/bearer patterns
validate input
rate-limit & HTTPS
77. XML-RPC API in Odoo
Classic integration method supported across versions.
XML-RPC idea
import xmlrpc.client
uid = common.authenticate(db, user, password, {})
models.execute_kw(db, uid, password, 'res.partner', 'search', [[['is_company', '=', True]]])
78. JSON-RPC API in Odoo
Same ORM methods as UI/RPC — respect access rights.
JSON-RPC tip
/jsonrpc endpoint
call authenticate / execute
JSON payloads
session or api key strategies
79. External API Integration in Odoo
Store credentials securely; handle timeouts and retries.
Integration tip
requests / httpx in server methods
system parameters for config
queue jobs for slow calls
log request ids
80. Webhooks Integration in Odoo
Verify signatures and make handlers idempotent.
Webhook tip
HTTP controller route
verify signature/secret
ack quickly, process async
idempotency keys
81. JavaScript in Odoo
Modern Odoo frontend centers on OWL and the assets bundle system.
JS tip
assets in manifest
/** @odoo-module **/
patch existing components
use services (rpc, notification)
82. OWL Framework in Odoo
OWL uses QWeb-like templates, hooks, and props similar to modern component frameworks.
OWL idea
Components + templates
state / hooks
props & env
mount in webclient
83. OWL Components in Odoo
Keep components small; fetch data via ORM/rpc services.
Component tip
// OWL component sketch
class Counter extends Component {
static template = 'my_module.Counter';
setup() {
this.state = useState({ value: 0 });
}
}
84. Odoo Frontend Development
Prefer extension/patch over forking core assets.
Frontend tip
Field widgets
View compilers
Systray items
SCSS assets
OWL services
85. Odoo Backend Customization
Follow upgrade-safe patterns: inherit, don’t edit core modules.
Backend tip
_inherit models
xpath views
automations & server actions
security for new fields/models
86. Custom Dashboard Development in Odoo
Start with KPI search views; move to OWL when UX needs are richer.
Dashboard tip
board module layouts
graph/pivot actions
client action + OWL
role-based menu visibility
87. Odoo Accounting Module
Enterprise vs Community accounting features differ — check your edition.
Accounting areas
CoA & taxes
Customer/vendor bills
Journals & reconciliation
Financial reports
88. Odoo Sales Module
Customizations often add fields on sale.order and order lines.
Sales tip
sale.order / sale.order.line
Confirm → delivery/invoice
Pricelists
Sales teams
89. Odoo Purchase Module
Integrate with inventory receipts and accounting.
Purchase tip
purchase.order
Vendor pricelists
Incoming shipments
3-way matching concepts
90. Odoo Inventory Module
Inventory is central — test customizations with multi-step routes carefully.
Inventory tip
product.product / template
stock.picking / move
Routes & rules
Valuation basics
91. Odoo CRM Module
Kanban + activities are core CRM UX patterns.
CRM tip
crm.lead
Stages & probabilities
Activities schedule
Lead enrichment optional
92. Odoo Manufacturing Module
Custom modules often extend BoM lines and MO worksheets.
MRP tip
mrp.bom
mrp.production
Work orders
Quality integrations optional
93. Odoo HR Module
HR data is sensitive — tighten record rules and access groups.
HR tip
hr.employee
Time off
Attendance
Payroll (edition-dependent)
94. Odoo Project Management
Link tasks to sales/helpdesk when building service flows.
Project tip
project.project / task
Stages & deadlines
Timesheets
Task dependencies
95. Odoo Website and E-commerce
Syncs with inventory, taxes, and payment providers.
eCommerce tip
Product pages
Cart & checkout
Payment providers
Shipping methods
Customer portal orders
96. Payment Gateway Integration in Odoo
Follow PCI-aware patterns; never log full card data.
Payment tip
payment.provider
Acquirer/provider modules
Callbacks & webhooks
Test mode first
97. Shipping Integration in Odoo
Use delivery methods on sales/transfers; store tracking references.
Shipping tip
delivery carriers
Rate computation
Label printing
Tracking URLs
98. Third-Party API Integration in Odoo
Isolate integration code in dedicated modules.
Connector tip
Auth (OAuth/API key)
Field mapping
Retry / queue jobs
Monitoring & alerts
99. Odoo Data Import
Use external IDs for idempotent re-imports and relational mapping.
Import tip
Enable import option
External ID column
Many2one by name/id
Validate before import
100. Odoo Data Export
For large extracts, prefer server-side reports or scripts.
Export tip
List → Export
Export all / selected fields
IDs + external IDs
Respect access rights
101. Database Migration in Odoo
Always backup DB + filestore; test on a staging copy first.
Migration tip
Backup first
Staging upgrade rehearsal
Module compatibility check
Scripts for data cleanup
102. Odoo Module Upgrade
Bump manifest version; write migration scripts in migrations/ when needed.
Upgrade tip
odoo-bin -c odoo.conf -d mydb -u my_module --stop-after-init
103. Odoo Debugging
Reproduce as a non-admin user to catch ACL/record rule issues.
Debug tip
--log-level=debug
_logger.info(...)
IDE attach to odoo-bin
Check ir.logging / traceback mail
104. Odoo Logging
Avoid logging secrets; structured messages help production support.
Logging
import logging
_logger = logging.getLogger(__name__)
_logger.info('Synced %s partners', len(partners))
105. Odoo Performance Optimization
Watch N+1 mapped loops; use prefetch and read_group for aggregates.
Perf checklist
Avoid N+1 searches in loops
Index domains fields
Batch crons
Workers + limits
Asset bundling in prod
106. Odoo Security Best Practices
Never bypass security with sudo() unless the operation is trusted and audited.
Security checklist
Strong admin_passwd
Least-privilege groups
Record rules for multi-company
Sanitize website controllers
Keep Odoo & Postgres patched
107. Git and Odoo Development Workflow
Ignore filestore, pyc, and local conf secrets.
Git tip
Repo = custom_addons
Branch per feature
PR + module upgrade test
Tag releases matching Odoo version
108. Odoo Module Testing
Tests protect upgrades and refactors of business logic.
Test tip
from odoo.tests.common import TransactionCase
class TestBook(TransactionCase):
def test_create_book(self):
book = self.env['library.book'].create({'name': 'Test'})
self.assertTrue(book.id)
109. Odoo Deployment
Separate staging/production DBs; automate backups of DB + filestore.
Deploy checklist
Nginx/Apache reverse proxy + SSL
systemd service
workers & memory limits
daily backups
monitoring / disk for filestore
110. Odoo Interview Questions
Be ready for ORM, inheritance, security, views, and upgrade topics.
Sample Q&A
Q: _name vs _inherit?
A: _name creates a model; _inherit extends an existing model.
Q: Many2one vs One2many?
A: Many2one stores FK; One2many is inverse list.
Q: Why record rules?
A: Row-level security beyond model ACL.
111. Real-World Odoo Development Project
Include security, views, reports, and a small automation in each project.
Project ideas
Library management
Maintenance requests
Sales commission fields
Inventory label wizard
Website lead form → CRM
112. Final Project – Complete Custom Odoo Module
Ship a production-shaped module (e.g., Library or Service Tickets): models + fields, list/form/search views, menus/actions, security groups/ACL/record rules, wizard, chatter/mail optional, QWeb report or email template, cron or automation, tests, and README with install/upgrade steps.
- Define the business model and states.
- Implement views, security, and wizard.
- Add report/automation and tests.
- Document install, upgrade, and demo data.
Final project scope
1. Custom module scaffold + manifest
2. Models with relations & constraints
3. Form/list/search (+ kanban optional)
4. Menus + window actions
5. Security groups + ACL + record rule
6. Wizard (TransientModel)
7. Smart button / status workflow
8. Report or email template
9. Cron or automated action
10. Tests + README + upgrade notes
Suggested structure
my_service_ticket/
models/
views/
security/
wizard/
report/
data/
tests/
Conclusion
You now have a full Odoo development path: modules, ORM, views, security, website/reports, integrations, and deployment. Finish the final custom Odoo module to turn the lessons into a portfolio-ready addon.