How to Implement filtered() with lambda, mapped in Odoo?
1. filtered_domain()
✅ What is it?
filtered_domain() is used to filter a recordset using domain-style conditions (as used in search methods).
✅ Syntax
filtered_records = recordset.filtered_domain([('field', 'operator', value)])
📌 Realistic Example
Suppose you want to process only confirmed sale orders (state = 'sale'):
confirmed_orders = self.filtered_domain([('state', '=', 'sale')])
for order in confirmed_orders:
order.message_post(body="Processed confirmed order.")
✅ When to use?
- When filtering based on record field values using Odoo's standard domain logic.
- Cleaner and more readable than Python-based filtering.
2. filtered() with lambda
✅ What is it?
filtered() is used to filter a recordset based on a Python function (usually a lambda expression).
✅ Syntax
filtered_records = recordset.filtered(lambda rec: rec.field > value)
📌 Realistic Example
Filter sale orders where total amount is greater than 1000:
high_value_orders = self.filtered(lambda order: order.amount_total > 1000)
for order in high_value_orders:
order.message_post(body="High-value order processed.")
✅ When to use?
- When filtering logic is too complex for a domain.
- Useful for conditions like: order.partner_id.is_company and order.amount_total > 1000
3. mapped()
✅ What is it?
mapped() is used to extract a specific field from a recordset or call a method on all records.
✅ Syntax
values = recordset.mapped('field_name')
📌 Realistic Example
Get all customer names from a list of sale orders:
partner_names = self.mapped('partner_id.name')
You can also chain fields:
emails = self.mapped('partner_id.email')
✅ When to use?
- To extract a list of field values from related models.
- To flatten results when fetching One2many or Many2one relationships.
✅ Combined Example
class SaleOrder(models.Model):
_inherit = 'sale.order'
def action_notify_high_value_customers(self):
high_value_orders = self.filtered(lambda o: o.amount_total > 1000)
confirmed_orders = high_value_orders.filtered_domain([('state', '=', 'sale')])
partner_emails = confirmed_orders.mapped('partner_id.email')
for email in partner_emails:
# Imagine sending email (this is just a placeholder)
_logger.info(f"Notification sent to: {email}")
✅ Summary Table
Feature | Purpose | Example Use Case |
---|---|---|
filtered_domain() | Filter records using domain logic | state == 'sale' |
filtered() | Filter using Python function/lambda | amount_total > 1000 |
mapped() | Extract field values from records | Get all customer names or emails from orders |