What is a Function Decorator?
Function decorators in Odoo (from the odoo.api module) define how methods behave in the ORM environment. They instruct Odoo on:
  • The type of input/output a method should handle.
  • Whether it acts on single or multiple records.
  • Whether it’s a model-level method, computed field, etc.

📌 Realistic Odoo Examples

1.  @api.model
Use when the method does not need a specific record (no self.id) but uses self.env.

@api.model

def get_default_currency(self):

    return self.env.user.company_id.currency_id​

2.  @api.multi (✅ Deprecated since Odoo 13)
Used for computed fields. Marks which fields trigger recomputation.​
  • Allowed looping over multiple records using self.
  • No longer required — modern Odoo methods support multiple records by default.

3. @api.depends(*fields) 

  • Declares field dependencies for computed fields.
  • Ensures the compute method re-runs when the listed fields change.

@api.depends(‘price_unit’, ‘quantity’)

def _compute_total(self):

    for line in self:

        line.total = line.price_unit * line.quantity

4. @api.constrains(*fields) 

  • Ensures validation logic when any of the fields listed change.

@api.constrains(‘discount’)

def _check_discount(self):

    if self.discount > 100:

        raise ValidationError(“Discount cannot exceed 100%.”)

5. @api.onchange(*fields)

Used for computed fields. Marks which fields trigger recomputation.​
  • Reacts to changes in the given fields, mainly in the UI/form views.
  • Does not save any values to the database unless explicitly returned.
6. @api.model_create_multi  ✅ (Newer and Advanced)

📌 Purpose:

Optimizes and supports bulk record creation by accepting a list of dictionaries and creating multiple records in one go.
✅ When to use:
  • In overridden create() methods when batch creation is required.
  • Improves performance over looping in @api.model.

📌 Example

from odoo import api, models

class CustomTag(models.Model):

    _name = ‘custom.tag’

    name = fields.Char()

   

 @api.model_create_multi

    def create(self, vals_list):

        # vals_list: list of dictionaries

        for vals in vals_list:

            if ‘name’ not in vals:

                raise ValidationError(“Name is required for each tag.”)

        return super().create(vals_list)

  • ✅ vals_list is a list of dictionaries, one for each record to be created.
  • ✅ Suitable when using XML-RPC or Odoo batch APIs.

✅ Summary Table

Decorator
Purpose
@api.model Model-level logic, no specific record needed
@api.depends(…) Recomputes field when dependencies change
@api.constrains(…) Validates field constraints
@api.onchange(…) UI-triggered updates (not saved to DB)
@api.model_create_multi Efficiently handles bulk record creation