In Odoo, method decorators are used to enhance or add functionality to the methods they decorate. These decorators are Python functions defined in Odoo/api.py and act as wrappers for other functions.
Here is a description of the key decorator methods in Odoo 16:
api.onchange
The on-change decorator is used with methods that should run when the value of certain fields in the form view changes. This decorator does not support field names with dots (eg relational fields like product_id.default_code), only simple field names.
Example:
@api.onchange('user_id')
def _onchange_user(self):
if self.user_id:
self.update(self._sync_user(self.user_id, (bool(self.image_1920))))
if not self.name:
self.name = self.user_id.name
api.autovacuum
Methods decorated with autovacuum are called by the daily vacuum cron job defined in the ir.autovacuum model. These methods typically handle tasks such as garbage collection that need to be run daily, eliminating the need to create dedicated cron jobs.
Example:
@api.autovacuum
def _gc_sessions(self, *args, **kwargs):
"""Remove wishlists for unexisting sessions."""
self.with_context(active_test=False).search([
("create_date", "<", fields.Datetime.to_string(datetime.now() - timedelta(weeks=kwargs.get('wishlist_week', 5)))),
("partner_id", "=", False),
]).unlink()
api.model
The model decorator is used for methods where self is a recordset, but only the model itself is relevant. This decorator helps with code migration by converting old API calls to the new API format, simplifying the migration process.
Example:
@api.model
def _get_production_location(self):
location = self.env['stock.location'].search([('usage', '=', 'production'), ('company_id', '=', self.company_id.id)], limit=1)
if not location:
raise UserError(_('Can\'t find any production location.'))
return location
api.model_create_multi
The model_create_multi decorator is used with methods that create multiple entries from a single dictionary or list of dictionaries.
Example:
@api.model_create_multi
def create(self, vals):
cashboxes = super(AccountBankStmtCashWizard, self).create(vals)
cashboxes._validate_cashbox()
return cashboxes
api.returns
The return decorator is for methods that return model instances. It requires a model name (as a string) and functions to upgrade or downgrade values between log-style and traditional-style outputs.
Example:
@api.returns('self', lambda value: value.id)
def copy(self, default=None):
default = dict(default or {},
name=_("%s (copy)", self.name))
return super().copy(default=default)
api.ondelete
The ondelete decorator indicates the methods to be called when records are disconnected. Prevents deletion of certain records based on specified conditions. Method names are usually of the format _unlink_if_<condition> or _unlink_except_<not_condition>.
Example:
@api.ondelete(at_uninstall=False)
def _unlink_if_no_variant(self):
if self.variant_report_ids:
raise UserError(_("You can't delete a report that has variants."))
api.depends
The depends decorator specifies the dependencies for a compute method. It accepts simple field names or dot-separated sequences of field names.
Example:
@api.depends('partner_id')
def _compute_name(self):
for lead in self:
if not lead.name and lead.partner_id and lead.partner_id.name:
lead.name = _("%s's opportunity") % lead.partner_id.name
api.depends_context
The depends_context decorator is used with unstored compute methods to specify context dependencies.
Example:
@api.depends_context('company')
def _compute_show_credit_limit(self):
for partner in self:
partner.show_credit_limit = self.env.company.account_use_credit_limit
api.constrains
A constraint decorator defines constraint dependencies for a method. Fires when the specified fields are included in a create or write call and are present in the view. A ValidationError is usually raised if the constraint fails.
Example:
@api.constrains('parent_id')
def _check_parent_id(self):
if not self._check_recursion():
raise ValidationError(_('You cannot create recursive departments.'))
These method decorators streamline code and enhance functionality within Odoo. To read more about method decorators in Odoo 17, refer to our blog An Overview of Method Decorators in Odoo 17