How to Implement read_group() in Odoo?
Overview
The read_group() method in Odoo is used for grouped data aggregation, similar to SQL's GROUP BY. It allows you to aggregate fields (e.g., count, sum) over a group of records directly from the database—making it highly efficient for reporting.
✅ Purpose
- Perform aggregation (e.g., count, sum, avg)
- Group records by one or more fields
- Use in dashboards, KPIs, and summarized reports
✅ Syntax
recordset.read_group(
domain,
fields,
groupby,
offset=0,
limit=None,
orderby=False,
lazy=True
)
Parameters
Parameter | Description |
domain | Filter conditions ([] for all records) |
fields | Fields to aggregate (with functions like sum:amount_total) |
groupby | Field(s) to group by |
lazy | If True, only the first level of groups is returned |
🧠 Realistic Odoo Example: Sales Grouped by Salesperson
results = self.env['sale.order'].read_group(
domain=[('state', '=', 'sale')],
fields=['amount_total:sum', 'user_id'],
groupby=['user_id']
)
for res in results:
print(f"{res['user_id'][1]} - Total: {res['amount_total']}")
✅ This returns the total sales per salesperson (user_id).
Example: Group Partners by Country
res = self.env['res.partner'].read_group(
domain=[],
fields=['country_id', 'id:count'],
groupby=['country_id']
)
# Output: [{'country_id': (12, 'India'), 'id_count': 56}, ...]
Example: Monthly Sales
res = self.env['sale.order'].read_group(
domain=[('state', '=', 'sale')],
fields=['amount_total:sum', 'date_order:month'],
groupby=['date_order:month']
)
✅ Aggregates total sales by month.
✅ Summary Table
Feature | Description |
Aggregation support | sum, count, avg, min, max |
Grouping | Yes, with one or multiple fields |
Efficient | Yes, works at DB level |
Lazy loading | Controls nested group expansion |
Use cases | Dashboards, KPIs, summarized reports |
⚠️ Notes
- read_group() does not return recordsets, but a list of dictionaries
- If grouping by many2one, result includes (id, name) tuple
- Requires fields in groupby to be stored fields