How to Override create, write, and unlink Methods in Odoo 18
In Odoo, the methods create, write, and unlink are core to how data is managed within the system. These are the go-to methods behind the scenes every time a record is created, updated, or deleted.
But what if your business process needs to go a step further? For example, maybe you want to enforce some custom validations, log certain changes, or control who can delete specific records. That’s where overriding these methods comes in handy.
Let’s walk through how to override these key methods in Odoo 18 the right way — clean, efficient, and maintainable.
What Are create, write, and unlink?
Before diving in, here’s a quick refresher:
- create(): Called when a new record is created.
- write(): Called when an existing record is updated.
- unlink(): Called when a record is deleted.
Overriding these allows us to add custom business logic before or after the standard operation takes place.
🔧 Overriding the create() Method
Let’s say you want to make sure that every partner (contact) in the system has a mobile number. You can override the create() method to validate this.
python
from odoo import models, api, exceptions
class ResPartner(models.Model):
_inherit = “res.partner”
@api.model_create_multi
def create(self, values_list):
for values in values_list:
if ‘mobile’ not in values or not values.get(‘mobile’):
raise exceptions.ValidationError(“Mobile number is required.”)
return super().create(values_list)
✅ Breakdown:
- @api.model_create_multi: Optimized for batch record creation.
- Validation check: If the mobile field is missing or empty, it raises an error.
- Super call: Ensures Odoo’s default create() logic is still executed.
🛠 Overriding the write() Method
Even if we validated the mobile number at creation, a user could later remove it during an update. So let’s make sure we enforce the same rule during record modification.
python
from odoo import models, exceptions
class ResPartner(models.Model):
_inherit = “res.partner”
def write(self, values):
if ‘mobile’ in values and not values[‘mobile’]:
raise exceptions.ValidationError(“Mobile number cannot be empty.”)
return super().write(values)
✅ Breakdown:
- Checks if mobile is part of the update and ensures it’s not empty.
- Calls the standard write() method after validation.
🗑️ Overriding the unlink() Method
Want to stop unauthorized users from deleting important records? Let’s restrict deletions to users with administrative access.
python
from odoo import models, exceptions
class ResPartner(models.Model):
_inherit = “res.partner”
def unlink(self):
if not self.env.user.has_group(‘base.group_erp_manager’):
raise exceptions.UserError(“Only administrators can delete partner records.”)
return super().unlink()
✅ Breakdown:
- User permission check: Uses has_group() to verify user role.
- Prevents non-admins from deleting records.
💡 Final Thoughts
Overriding create(), write(), and unlink() in Odoo 18 is a powerful way to:
- Enforce business rules
- Prevent data inconsistency
- Add validations and access control
- Extend Odoo’s default behavior without breaking the core
Just remember:
- Always call super() to retain standard Odoo behavior.
- Keep your logic clean and maintainable.
Validate your data wisely to avoid headaches down the road.
This kind of control gives you the flexibility to mold Odoo to truly fit your business — and that’s where the real power of customization shines.
Unlock powerful custom logic in Odoo 18—secure, scalable, and maintainab