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)

  • 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