Odoo 18 introduces powerful tools for database management, and one of the essential features for developers to understand is the ondelete
policy. This mechanism plays a critical role in managing how related records are handled when a parent record is deleted. Whether you’re managing simple models or complex relationships, grasping the concept of ondelete
policies ensures data consistency and prevents unexpected issues in your Odoo applications.
What is ondelete
in Odoo?
The ondelete
parameter is used in relational fields such as Many2one
, One2many
, and Many2many
to define the behavior of child records when a parent record is deleted. It helps maintain referential integrity in the database by specifying what action should be taken on the related records.
For example, consider a Many2one
relationship between an Order
model and a Customer
model:
class Order(models.Model):
_name = 'my_module.order'
name = fields.Char(string="Order Reference")
customer_id = fields.Many2one(
'my_module.customer', string="Customer", ondelete='cascade'
)
In this case, the ondelete
policy dictates what happens to orders when a customer is deleted
Available ondelete
Policies
Here are the most common ondelete
policies you can use in Odoo:
1. cascade
- Deletes the child records when the parent record is deleted.
- Use case: You want to ensure no orphaned records remain.
- Example:
customer_id = fields.Many2one('res.partner', ondelete='cascade')
2. set null
- Sets the value of the relational field to
NULL
in the child records when the parent record is deleted. - Use case: You want the child records to remain but without a link to the deleted parent.
- Example:
customer_id = fields.Many2one('res.partner', ondelete='set null')
3. restrict
- Prevents the deletion of the parent record if there are related child records.
- Use case: You want to enforce a strict dependency between parent and child records
- Example:
customer_id = fields.Many2one('res.partner', ondelete='restrict')
4. set default
- Sets the relational field to a default value when the parent record is deleted.
- Use case: You want to replace the deleted parent with a default value in child records.
- Example:
customer_id = fields.Many2one('res.partner', ondelete='set default')
5. no action
- Does nothing to the child records when the parent record is deleted. This is the default behavior if no
ondelete
is specified. - Use case: You want complete control over the behavior through custom logic.
- Example:
customer_id = fields.Many2one('res.partner', ondelete='no action')
Practical Scenarios:
- Managing Orders and Customers: If a customer is deleted, their orders should also be removed to avoid orphaned records:
customer_id = fields.Many2one('res.partner', ondelete='cascade')
- Employee and Manager Relationship: If a manager is deleted, employees should remain but without a link to the manager:
manager_id = fields.Many2one('hr.employee', ondelete='set null')
- Prevent Deletion of Records with Dependencies: To prevent deleting a product category if products are assigned to it:
category_id = fields.Many2one('product.category', ondelete='restrict')