Odoo Custom Module Development Part 5 - Relations, Computed Fields, and Business Logic
This is the fifth article in the Odoo custom module development series.
In Part 4, we added the user interface. In this article, we will make the module smarter by adding relations, computed fields, onchange logic, constraints, and object methods.
This is where a simple CRUD module starts becoming a real business application.
What we will add
We will add:
- property type relation
- salesperson relation
- buyer relation
- computed total area
- a computed price helper field
- onchange behavior for garden fields
- validation constraints
- action buttons to sell or cancel a property
1. Add relational fields to estate.property
Update models/property.py:
from odoo import api, fields, models |
In a more advanced version of this module, best_price would usually be computed from related offer records. Here we keep it simple so you can learn computed fields without introducing another model yet.
2. Why these field types matter
Many2one: one property belongs to one type, one buyer, one salesperson- computed fields: values are derived automatically from other fields
@api.onchange: improves the form experience before saving- constraints: stop invalid business data from entering the database
- object methods: let buttons execute business transitions
3. Show the new fields in the form view
Update the property form view in estate_property_views.xml:
<form string="Property"> |
This adds visible business behavior to the UI.
4. Add fields to the list view
Update the list view so users can quickly scan important values:
<list string="Properties"> |
5. Add SQL-level protection if needed
Python constraints are good for business rules, but some cases also benefit from SQL constraints.
Example:
_sql_constraints = [ |
Use SQL constraints for simple database-safe guarantees. Use Python constraints when the rule is more complex.
6. Upgrade the module and test behavior
Run:
cd ~/odoo-dev/odoo |
Then test these scenarios from the UI:
- create a property with
expected_price = 0and confirm validation fails - toggle
gardenon and off and confirm the onchange logic updates the fields - click
Mark as Sold - try to cancel a sold property and confirm the error is raised
7. Best practices for business logic in Odoo
- keep business rules in Python methods, not only in the UI
- use constraints for validation, not manual reminders in help text
- use object methods for state transitions
- make state changes explicit and readable
- avoid putting serious business logic inside onchange methods because onchange only runs in the UI
8. Common mistakes
Relying only on onchange for validation
@api.onchange does not protect imports, server-side operations, or API calls. Use constraints for real validation.
Forgetting store=True for a computed field you want to search or group by
Non-stored computed fields are recalculated dynamically and are not always suitable for filtering or grouping.
Putting too much logic in button methods without state checks
Always validate the current state before allowing a transition.
Final words
Your module now has meaningful business logic and workflow behavior.
In the next article, we will add sample data, PDF reporting, and automated tests so the module becomes easier to demonstrate and maintain.
Previous article: Part 4 - Menus, Actions, and Views
Next article: Part 6 - Reports, Demo Data, and Tests
Related posts
- /article/odoo-custom-module-development-part-2-models-and-fields/
- /article/odoo-custom-module-development-part-1-create-your-first-module/
- /article/odoo-custom-module-development-part-3-security-and-access-rights/
- /article/odoo-custom-module-development-part-6-reports-demo-data-and-tests/
- /article/odoo-custom-module-development-part-4-menus-actions-and-views/