Mastering Record Search Techniques in Odoo 19: A Complete Developer’s Guide
In the world of modern business management, ERP Consultation plays a vital role in optimizing workflows and data organization. Within the Odoo ecosystem, one of the most powerful features developers rely on is its record search functionality. Odoo 19 has further refined this with improved speed, enhanced AI suggestions, and seamless integration for both the Community and Enterprise editions. Understanding how to perform effective searches is crucial for developers, consultants, and power users who need to retrieve specific data quickly and accurately.
This blog provides an in-depth look into how to search records in Odoo 19, covering all the major techniques—from basic domain searches to read group aggregations. By mastering these methods, you can ensure that your Odoo modules deliver faster queries, better reporting, and smoother user experiences.
Understanding Record Search in Odoo 19
Odoo’s search functionality operates through its Object-Relational Mapping (ORM) system. Developers interact with models using methods such as search() and search_count(), which query the underlying database efficiently. These searches rely on domains, which are Python lists containing tuples that define filtering conditions.
A domain in Odoo typically looks like this:
[('field_name', 'operator', 'value')]
Each tuple acts as a filter condition—for example, ('is_active', '=', True) retrieves all active records. Multiple conditions can be combined to perform advanced filtering, making the search system both flexible and powerful.
Domains can be used in Python backend code or within XML view definitions for frontend filters, allowing dynamic and user-friendly data interaction.
Setting Up the Example Model
To better understand search methods, let’s work with a simple example model called custom.partner. This model represents business partners and includes fields for name, email, category, activity status, creation date, and sales count.
from odoo import fields, models
class Partner(models.Model):
_name = 'custom.partner'
_description = 'Custom Partner'
name = fields.Char(string='Name', required=True)
email = fields.Char(string='Email')
category = fields.Selection([
('gold', 'Gold'),
('silver', 'Silver')
], string='Category')
is_active = fields.Boolean(string='Active', default=True)
create_date = fields.Date(string='Creation Date')
sales_count = fields.Integer(string='Sales Count')
This sample model will be used throughout the guide to demonstrate different ways to search and filter records effectively.
1. Basic Domain Search
The most fundamental search method in Odoo is the search() function. It allows you to retrieve records matching specific conditions.
Example:
partners = self.env['custom.partner'].search([
('is_active', '=', True),
('category', '=', 'gold')
])
for partner in partners:
print(partner.name)
In this example, Odoo fetches all active partners belonging to the "Gold" category. The result is a recordset, which you can iterate through to access individual records.
You can also expose similar filters in the frontend XML search view:
<search string="Partners">
<filter string="Active" name="active" domain="[('is_active', '=', True)]"/>
<filter string="Gold Category" name="gold" domain="[('category', '=', 'gold')]"/>
</search>
2. Complex Domain Searches
Complex domains help you perform multi-layered filtering, including conditions involving related fields or nested logic.
Example:
from datetime import date
partners = self.env['custom.partner'].search([
('create_date', '>', date(2025, 1, 1)),
('email', 'ilike', '%example.com')
])
Here, you’re filtering partners created after January 1, 2025, and whose email contains “example.com”. The ilike operator ensures the search is case-insensitive.
Such complex domains are particularly useful in large ERP systems where business rules often require multi-condition filtering.
3. Using OR and AND Operators
Odoo domains allow logical operators to combine conditions flexibly.
-
|represents OR -
&represents AND
By default, conditions in a domain are combined using AND, but when mixing logic, explicit operators ensure clarity.
Example (OR):
partners = self.env['custom.partner'].search([
'|',
('category', '=', 'gold'),
('sales_count', '>', 10)
])
This retrieves all partners who are either in the “Gold” category or have more than 10 sales.
Example (AND):
partners = self.env['custom.partner'].search([
'&',
('is_active', '=', True),
('category', '=', 'silver')
])
This returns all active partners in the “Silver” category.
Logical operators help developers build dynamic queries that can adapt to complex data structures, making Odoo searches more precise and efficient.
4. Search Count
When you only need the number of records instead of the records themselves, use search_count(). It’s faster and consumes fewer resources.
Example:
count = self.env['custom.partner'].search_count([('is_active', '=', True)])
print(f"Active partners: {count}")
This method is ideal for dashboards, summaries, and reports where displaying the total number is sufficient. For instance, an ERP consultant might use this in a KPI widget to display active customer counts.
5. Searching with Context
Odoo’s context mechanism allows you to modify search behavior dynamically. Contexts can be used to add default filters, limit search results, or change the way data is retrieved.
Example:
self = self.with_context(category_filter='gold')
partners = self.env['custom.partner'].search([])
You can override the _search() method to include context-based logic:
@api.model
def _search(self, args, offset=0, limit=None, order=None, access_rights_uid=None):
if self._context.get('category_filter'):
args += [('category', '=', self._context['category_filter'])]
return super()._search(args, offset, limit, order, access_rights_uid)
And in an action:
<record id="action_partner_gold" model="ir.actions.act_window">
<field name="name">Gold Partners</field>
<field name="res_model">custom.partner</field>
<field name="view_mode">tree,form</field>
<field name="context">{'category_filter': 'gold'}</field>
</record>
This approach simplifies code maintenance and improves user experience by applying automatic filters based on user actions or roles.
6. Grouping and Aggregation with Read Group
The read_group() method is used to perform grouped searches, similar to SQL’s GROUP BY. It helps summarize and analyze data efficiently.
Example:
groups = self.env['custom.partner'].read_group(
domain=[('is_active', '=', True)],
fields=['category', 'sales_count:sum'],
groupby=['category']
)
for group in groups:
print(f"Category: {group['category']}, Count: {group['__count']}, Total Sales: {group['sales_count']}")
This example groups all active partners by category, counting how many belong to each and summing their total sales. Such aggregated data is extremely useful for ERP reporting, performance tracking, and business analysis.
Conclusion
Mastering record search techniques in Odoo 19 empowers developers and consultants to create efficient, scalable, and data-driven ERP systems. From simple domain filters to advanced read group aggregations, every search method plays a crucial role in optimizing performance and usability.
For professionals involved in ERP consultation, understanding how Odoo retrieves, filters, and structures data is a game changer. Whether you’re building dashboards, custom modules, or automated reports, Odoo 19’s enhanced search tools make data access faster, smarter, and more intuitive. By leveraging these techniques, you can design solutions that truly align with business needs—turning raw data into actionable insights.
- Art
- Causes
- Crafts
- Dance
- Drinks
- Film
- Fitness
- Food
- الألعاب
- Gardening
- Health
- الرئيسية
- Literature
- Music
- Networking
- أخرى
- Party
- Religion
- Shopping
- Sports
- Theater
- Wellness