In Odoo 17, decorators modify the behavior of methods within models, controllers, and other components. The decorators are used to add functionalities or modify the existing ones of the function to which the decorator is added.
Here are some commonly used decorators in Odoo 17:
@api.model
In Odoo, the ‘@api.model’ decorator is indeed used for methods where the ‘self’ represents a record set, but only the model itself is relevant, not its records. This decorator is particularly useful during code migration from older versions of Odoo to newer ones.
@api.model
def get_total_books(self):
"""
Method to get the total number of books in the library.
This method only deals with the Library model itself.
"""
library_count = self.env['library'].search_count([])
return library_count
@api.autovacuum
The ‘ @api.autovacuum’ decorator in Odoo schedules methods to run with the daily vacuum cron job (ir.autovacuum). It's ideal for executing garbage collection-like tasks that require daily cleanup without needing a dedicated cron job entry. This decorator simplifies maintenance and ensures database optimization by automating routine cleanup operations.
@api.autovacuum
def remove_inactive_users(self):
"""Remove inactive user records."""
self.env['res.users'].search([('active', '=', False)]).unlink()
@api.constrains
The ‘@api.constrains’ decorator in Odoo specifies constraint dependencies for a method, triggering it only when certain specified fields are included in the creating or writing call, and if they are present in the view. It supports only simple field names and ignores dotted names. Typically, this decorator is used to raise a ValidationError if the check fails.
@api.constrains('amount_total')
def _check_amount_total(self):
for order in self:
if order.amount_total <= 0:
raise ValidationError("The total amount of the order must be greater than zero.")
@api.depends
The ‘@api.depends’ decorator in Odoo is used to specify field dependencies for computed fields. It informs Odoo that the computed field's value depends on the values of other fields, ensuring that the computed field is recalculated whenever any of its dependencies change.
@api.depends('cost_price', 'sale_price')
def _compute_profit_margin(self):
for product in self:
if product.cost_price and product.sale_price:
product.profit_margin = ((product.sale_price - product.cost_price) / product.cost_price) * 100
else:
product.profit_margin = 0.0
This function is recomputed whenever there is a change in the fields ‘cost_price’ and ‘sale_price’.
@api.model_create_multi
The Odoo @api.multi decorator creates multiple records from a single or a list of dictionaries. It's useful for bulk record creation, improving efficiency and productivity. The values are conveyed as parameters to the method.
@api.model_create_multi
def create(self, vals):
cashboxes = super(AccountBankStmtCashWizard, self).create(vals)
cashboxes._validate_cashbox()
return cashboxes
@api.onchange
The ‘@api.onchange’ decorator in Odoo automatically triggers methods in response to changes in specified fields within form views. By marking a method with this decorator within a model, these methods are invoked whenever the designated fields are modified, facilitating dynamic updates and actions based on user input.
@api.onchange('partner_id')
def _onchange_partner_id(self):
if self.partner_id:
self.payment_term_id = self.partner_id.payment_term_id
@api.ondelete
The ‘@api.ondelete’ decorator in Odoo marks a method to be called when records are being unlinked (deleted). It's often used to prevent the deletion of records, such as lines on posted entries, during module uninstallation, which cannot be achieved by overriding the unlink() method.
Parameters:
* at_uninstall: A boolean parameter indicating whether the decorated method should be called during module uninstallation. If False, errors raised by the method won't prevent module uninstallation.
@api.ondelete(at_uninstall=False)
def _unlink_if_not_done(self):
if any(batch.state == 'done' for batch in self):
raise UserError(_("You cannot delete Done batch transfers."))
@api.returns
The ‘@api.returns’ decorator is used to specify the return type of methods that return instances of a particular model. It adapts the method output to the Odoo API style, either traditional style (returning ids or False) or record style (returning recordset).
Parameters:
* model: Specifies the model name or 'self' for the current model.
* downgrade: Optional function to convert the record-style output to traditional-style output.
* upgrade: Optional function to convert the traditional-style output to record-style output.
@api.model
@api.returns('res.partner')
def find_partner(self, arg):
# Return some record
return self.env['res.partner'].search([('name', '=', arg)])
# Traditional style call
partner_id = model.find_partner(arg)
# Record style call
partner_record = recs.find_partner(arg)
In conclusion, decorators serve various purposes, such as enhancing database maintenance, ensuring data integrity, and facilitating dynamic behavior in response to user actions. Understanding and leveraging these decorators is essential for efficient and effective Odoo development.
To read more about method decorators, refer to our blog Method Decorators in Odoo 15