Enable Dark Mode!
what-are-the-dependencies-with-apidepends.jpg
By: Anupriya Ashok

What are the Dependencies with @api.depends

Technical Odoo Enterprises Odoo Community

In Odoo, dependencies with @api.depends are decorators that define computed fields and indicate which fields they rely on. You can instruct Odoo to automatically recalculate a computed field whenever any of its dependent fields change by using @api.depends. This removes the need for manual field updates and guarantees data consistency.

Understanding Computed Fields in Odoo

Instead of being directly stored in the database, computed fields have their values automatically determined based on other fields. To create these computed fields effectively, the @api.depends decorator is necessary.

amount_untaxed = fields.Float(string='Untaxed Amount')
   amount_tax = fields.Float(string='Tax Amount')
   amount_total = fields.Float(string='Total Amount',     compute='_compute_amount_total')
   @api.depends('amount_untaxed', 'amount_tax')
   def _compute_amount_total(self):
       for record in self:
           record.amount_total = record.amount_untaxed + record.amount_tax

In this example, amount_total will automatically recalculate whenever amount_untaxed or amount_tax changes.

How @api.depends Works

When any of the designated fields are changed, the @api.depends decorator notifies the compute method. This system guarantees that calculated values are always correct and current.

Important traits:

Field names are passed as string arguments to the decorator. Multiple fields can be specified, with commas used to separate them. Odoo takes care of the recalculation automatically. Performance is enhanced by only calling the compute method when required.

Working with Related Fields

You can use dot notation to depend on fields from related models. This is particularly useful when you need to compute values based on data from linked records.

order_id = fields.Many2one('sale.order', string='Order')
   product_id = fields.Many2one('product.product', string='Product')
   quantity = fields.Float(string='Quantity')
   price_unit = fields.Float(string='Unit Price', related='product_id.list_price')
   subtotal = fields.Float(string='Subtotal', compute='_compute_subtotal')
   @api.depends('quantity', 'product_id.list_price')
   def _compute_subtotal(self):
       for line in self:
           line.subtotal = line.quantity * line.product_id.list_price

Here, the subtotal depends on both the line's quantity and the product's list price from the related product model.

Multiple Level Dependencies

You can chain dependencies across multiple related models using dot notation to traverse relationships.

@api.depends('order_line_ids.product_id.categ_id.name')
def _compute_category_summary(self):
   for order in self:
       categories = order.order_line_ids.mapped('product_id.categ_id.name')
       order.category_summary = ', '.join(set(categories))

Depending on One2many and Many2many Fields

When depending on One2many or Many2many fields, you typically need to specify which fields within those related records trigger the recalculation.

   order_line = fields.One2many('purchase.order.line', 'order_id', string='Order Lines')
  
 total_quantity = fields.Float(string='Total Quantity', compute='_compute_total_quantity')
   @api.depends('order_line.product_qty')
   def _compute_total_quantity(self):
       for order in self:
           order.total_quantity = sum(order.order_line.mapped('product_qty'))

Stored vs Non-Stored Computed Fields

Computed fields can be stored in the database or calculated on-the-fly. Adding store=True to a computed field definition saves the calculated value to the database.

amount_total = fields.Float(
   string='Total Amount',
   compute='_compute_amount_total',
   store=True
)

Benefits of storing computed fields:

  • Because values are pre-calculated, retrieval is faster.
  • is applicable to filters and database queries.
  • Sortable and searchable in list views
  • automatically updated in response to changes in dependencies

Common Failures and Effective Solutions

Always specify all dependencies. If you forget to include a field in @api.depends, the computed field won't update when that field changes, leading to incorrect data.

Use self iteration. Always iterate through records using for record in self within compute methods to handle recordsets properly.

Avoid circular dependencies. Don't create situations where Field A depends on Field B, and Field B depends on Field A.

Performance considerations. Be cautious with dependencies on large One2many fields or deeply nested related fields, as they can impact performance.

Practical Example: Invoice Computation

Here's a comprehensive example showing how @api.depends works in a real-world invoice scenario:

invoice_line_ids = fields.One2many('account.invoice.line', 'invoice_id', string='Invoice Lines')
   amount_untaxed = fields.Float(string='Untaxed Amount', compute='_compute_amounts', store=True)
   amount_tax = fields.Float(string='Tax Amount', compute='_compute_amounts', store=True)
   amount_total = fields.Float(string='Total Amount', compute='_compute_amounts', store=True)
   @api.depends('invoice_line_ids.price_subtotal', 'invoice_line_ids.price_tax')
   def _compute_amounts(self):
       for invoice in self:
           invoice.amount_untaxed = sum(invoice.invoice_line_ids.mapped('price_subtotal'))
           invoice.amount_tax = sum(invoice.invoice_line_ids.mapped('price_tax'))
           invoice.amount_total = invoice.amount_untaxed + invoice.amount_tax

Debugging Dependencies

When your computed fields aren't updating as expected, check these common issues:

  • Verify all dependent fields are listed in @api.depends
  • Ensure field names are spelled correctly
  • Check that related field paths are valid
  • Confirm that the compute method is properly iterating through records
  • Look for any exceptions being raised within the compute method

To read more about How to Add a Computed Field in Odoo 19, refer to our blog How to Add a Computed Field in Odoo 19.


Frequently Asked Questions

What happens if I don't use @api.depends on a computed field?

If you don't use @api.depends, the computed field will only calculate when explicitly called or when the record is loaded, not when related fields change. This can lead to stale or incorrect data.

Can I use @api.depends with multiple compute methods?

Yes, you can have multiple compute methods in the same model, each with its own @api.depends decorator specifying different dependencies.

How do I depend on all fields in a One2many relationship?

You need to explicitly specify which fields within the One2many records you depend on, like @api.depends('line_ids.field_name'). You cannot depend on the entire One2many field without specifying sub-fields.

Does @api.depends work with custom fields added through inheritance?

Yes, @api.depends works with inherited models and custom fields. Just ensure you reference the correct field names as they appear in the model.

Can computed fields with @api.depends be manually modified by users?

By default, computed fields are read-only. However, you can make them editable by adding an inverse method, which defines how to write values back to the dependent fields.

What's the difference between @api.depends and @api.onchange?

@api.depends is used for computed fields and triggers recalculation when dependencies change in the database. @api.onchange is used for form interactions and triggers when users change field values in the UI before saving.

If you need any assistance in odoo, we are online, please chat with us.



0
Comments



Leave a comment



whatsapp_icon
location

Calicut

Cybrosys Technologies Pvt. Ltd.
Neospace, KINFRA Techno Park
Kakkanchery, Calicut
Kerala, India - 673635

location

Kochi

Cybrosys Technologies Pvt. Ltd.
1st Floor, Thapasya Building,
Infopark, Kakkanad,
Kochi, India - 682030.

location

Bangalore

Cybrosys Techno Solutions
The Estate, 8th Floor,
Dickenson Road,
Bangalore, India - 560042

Send Us A Message