Enable Dark Mode!
overview-of-unlink-orm-method-in-odoo-19.jpg
By: Muhammed Fahis V P

Overview of unlink() ORM Method in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

The unlink() method is one of the most basic ORM methods in Odoo, used in deleting a record from the database. It is expected that whenever a developer needs to delete records from Odoo, unlink is always used. This is because the ORM will automatically handle several critical checks to ensure that the deletions do not break business logic or corrupt related data.

Since deletes can break data integrity, the unlink() method provides the interface between Odoo models so that consistency is enforced and unintended data loss is prevented during deletes.

What is the unlink() Method?

unlink() is the method that removes already existing records in a model. It works on a recordset, removing the corresponding rows from the database only after all the required validations and checks are performed.

Unlike direct SQL deletes, calling unlink() ensures that Odoo's internal mechanisms are respected. When a record is deleted using unlink(), Odoo automatically triggers:

  • Access rights validation
  • Record rules
  • ondelete behaviors of relational fields
  • Any custom deletion logic defined by developers

Because of this, unlink() is always the recommended approach for deleting records in Odoo.

Syntax

recordset.unlink()

Returns

  • True if the deletion is successful
  • Raises an exception if deletion is not allowed

Deleting Records Using unlink()

The most common usage of unlink() is deleting one or more records that are retrieved using browse() or search().

Example: Deleting a Single Record

partner = self.env['res.partner'].browse(10)
partner.unlink()

This removes the partner record with ID 10, as long as no access rules, record rules, or relational constraints prevent the deletion.

Deleting Multiple Records at Once

The Odoo ORM is optimized for batch operations. When unlink() is called on a recordset containing multiple records, Odoo deletes all of them in a single operation instead of executing separate delete queries.

Example: Deleting Cancelled Sales Orders

orders = self.env['sale.order'].search([('state', '=', 'cancel')])
orders.unlink()

This approach is efficient and avoids unnecessary database calls, making it suitable for cleanup operations and bulk deletions.

Overriding the unlink() Method in Odoo 19

In real-world applications, developers often need to restrict or customize deletion behavior based on business requirements. This can be achieved by overriding the unlink() method in a custom module.

Example: Prevent Deleting Confirmed Sales Orders

from odoo import models
from odoo.exceptions import UserError
class SaleOrder(models.Model):
    _inherit = 'sale.order'
    def unlink(self):
        for order in self:
            if order.state == 'sale':
                raise UserError(
                    "You cannot delete a confirmed Sales Order."
                )
        return super().unlink()

In this example, confirmed sales orders are protected from deletion, ensuring that important business documents are not removed accidentally.

Using @api.ondelete for Deletion Validations 

In Odoo 19, deletion-related validations are best handled using the @api.ondelete decorator. This decorator allows developers to define checks that are automatically triggered when a record is about to be deleted, without overriding the unlink() method itself.

Using @api.ondelete keeps deletion logic clean and focused. Odoo calls these methods before removing records, making it an ideal place to enforce business rules such as preventing deletion based on record state. This approach also avoids conflicts when multiple modules add deletion logic to the same model.

Example: Using @api.ondelete

from odoo import models, api
from odoo.exceptions import UserError
class SaleOrder(models.Model):
    _inherit = 'sale.order'
    @api.ondelete(at_uninstall=False)
    def _check_before_delete(self):
        for record in self:
            if record.state == 'sale':
                raise UserError(
                    "Confirmed Sales Orders cannot be deleted."
                )

This method is executed automatically during deletion. If the condition is met, an error is raised and the record is not removed, ensuring important business data remains protected.

unlink() and Relational Field Behavior

When deleting records, Odoo follows the ondelete behavior defined on relational fields such as Many2one. These behaviors determine what happens to related records when a record is removed.

Common ondelete options include:

  • cascade – Deletes related records
  • set null – Clears the relation
  • restrict – Prevents deletion
  • set default – Applies the default value

Example: Restrict Deletion

partner_id = fields.Many2one(
    'res.partner',
    ondelete='restrict'
)

If this field configuration is used, Odoo will block deletion when the record is still referenced elsewhere.

Validations Inside unlink()

Business rules often require restricting deletion based on a record’s state or usage. The unlink() method, or preferably @api.ondelete, is the ideal place to enforce such rules.

Example: Prevent Deleting Posted Journal Entries

from odoo import models
from odoo.exceptions import ValidationError
class AccountMove(models.Model):
    _inherit = 'account.move'
    def unlink(self):
        for move in self:
            if move.state == 'posted':
                raise ValidationError(
                    "Posted journal entries cannot be deleted."
                )
        return super().unlink()

This ensures accounting data remains consistent and prevents the removal of legally significant records.

Best Practices When Using unlink() in Odoo 19

To ensure safe and maintainable deletion logic in Odoo 19, developers should always use unlink() instead of raw SQL queries. Deletion validations should preferably be implemented using the @api.ondelete decorator rather than overriding unlink() unless it is absolutely necessary. Heavy business logic should be avoided inside unlink() to maintain good performance. Batch deletions should be performed on recordsets instead of deleting records one by one. Finally, user-friendly error messages should always be raised to clearly explain why a deletion is restricted.

The unlink() ORM method is a fundamental part of Odoo 19’s backend framework, providing a secure and controlled way to remove records from the database. By enforcing access rules, handling relational constraints, and allowing developers to inject business logic through method overrides or @api.ondelete, unlink() helps preserve data integrity across the system. From simple deletions to complex real-world restrictions, mastering the unlink() method is essential for building robust and production-ready Odoo applications.

To read more about Overview Of Read() ORM Method in Odoo 19, refer to our blog Overview Of Read() ORM Method in Odoo 19.


Frequently Asked Questions

What does the unlink() method do?

It permanently deletes records from the database while respecting Odoo’s access rules and constraints.

Is unlink() safer than using SQL DELETE?

Yes. unlink() ensures business logic, record rules, and relational behaviors are applied correctly.

Can unlink() delete multiple records at once?

Yes. It works on recordsets and deletes all selected records in a single operation.

Can deletion be restricted using unlink()?

Yes. Developers can block deletion based on conditions such as record state or usage.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



Recent Posts

whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, Kinfra Techno Park
Kakkancherry, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message