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