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