Enable Dark Mode!
how-to-search-records-in-odoo-19.jpg
By: Ayana R

How to Search Records in Odoo 19

Technical Odoo 19 Odoo Enterprises Odoo Community

Odoo, the powerful open-source ERP platform, provides robust tools for searching and filtering records to meet diverse business needs. Whether you're retrieving customer data, filtering sales orders, or generating reports, mastering record search techniques in Odoo is essential for developers and power users. In Odoo 19, search capabilities are enhanced with improved performance, AI-driven query suggestions, and seamless integration with custom modules, making it easier to query data efficiently.

This guide explores the key methods for searching records in Odoo 19, covering Basic Domain Search, Complex Domains, Search with OR/AND Operators, Search Count, Search with Context, and Search with Read Group. Aimed at developers, this blog provides practical examples, best practices, and insights to help you harness Odoo's search functionality.

Understanding Record Search in Odoo

In Odoo, searching records involves querying the database through models using methods like search() and search_count(), often with domains to filter results. Domains are lists of conditions (e.g., [('field', '=', value)]) that define which records to retrieve.

Searches can be performed in Python (backend) or via XML view definitions (frontend), and they support dynamic filtering, grouping, and context-based modifications. Let’s dive into each search technique with examples based on a custom "Partner" model.

Setting Up the Example Model

For consistency, we’ll use a simple custom.partner model:

# models/partner.py
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')

Basic Domain Search

The search() method is the foundation of record retrieval in Odoo, using a domain to filter records.

  • How It Works: The search() method takes a domain as a list of tuples, where each tuple is a condition in the format (field, operator, value). Common operators include =, !=, >, <, like, ilike, and in.
  • Use Case: Retrieve all active partners with the "Gold" category.

Example:

# Search active gold partners
partners = self.env['custom.partner'].search([('is_active', '=', True), ('category', '=', 'gold')])
for partner in partners:
    print(partner.name)

Explanation: This queries the custom.partner model, returning records where is_active is True and category is gold. The result is a recordset you can iterate over.

Frontend: In XML views, define a search view:

<search string="Partners">
    <filter string="Active" name="active" domain="[('is_active', '=', True)]"/>
    <filter string="Gold Category" name="gold" domain="[('category', '=', 'gold')]"/>
</search>

Complex Domains

Complex domains combine multiple conditions, often involving related fields or nested logic.

  • How It Works: Use dot notation to access related fields (e.g., field1.field2) or combine conditions for intricate filtering. Complex domains can include multiple fields, operators, or even sub-domains.
  • Use Case: Find partners created after January 1, 2025, with an email containing "example.com".

Example:

from datetime import date
partners = self.env['custom.partner'].search([
    ('create_date', '>', date(2025, 1, 1)),
    ('email', 'ilike', '%example.com')
])
for partner in partners:
    print(partner.name, partner.email)

Explanation: This filters partners by creation date and email domain. The ilike operator performs a case-insensitive search.

Frontend: Add to a search view:

<search string="Partners">
    <filter string="Created After 2025" name="recent" domain="[('create_date', '>', '2025-01-01')]"/>
    <filter string="Example Domain" name="example_email" domain="[('email', 'ilike', '%example.com')]"/>
</search>

Search with OR/AND Operators

Odoo domains support logical operators (& for AND,  for OR) to combine conditions flexibly.

  • How It Works: By default, conditions in a domain are ANDed. Use for OR and & explicitly for AND when mixing operators. Operators are written in prefix notation (before the conditions they apply to).
  • Use Case: Find partners who are either "Gold" or have more than 10 sales.

Example:

partners = self.env['custom.partner'].search([
    '|',  # OR operator
    ('category', '=', 'gold'),
    ('sales_count', '>', 10)
])
for partner in partners:
    print(partner.name, partner.category, partner.sales_count)

Explanation: The operator ensures records match either condition. For AND, you can write:

partners = self.env['custom.partner'].search([
    '&',  # AND operator (optional, implicit by default)
    ('category', '=', 'gold'),
    ('is_active', '=', True)
])

Frontend: Combine in search views:

<search string="Partners">
    <filter string="Gold or High Sales" name="gold_or_sales" domain="['|', ('category', '=', 'gold'), ('sales_count', '>', 10)]"/>
</search>
  • Best Practice: Group conditions clearly with parentheses in complex domains for readability

Search Count

The search_count() method returns the number of records matching a domain, without fetching the full recordset.

  • How It Works: It’s a lightweight alternative to search() when you only need a count, reducing database load.
  • Use Case: Count active partners.

Example:

active_count = self.env['custom.partner'].search_count([('is_active', '=', True)])
print(f"Active Partners: {active_count}")

Explanation: This returns an integer (e.g., 42) instead of a recordset, ideal for dashboards or validations.

Search with Context

Context in Odoo modifies search behavior, such as applying default filters or altering results dynamically.

  • How It Works: The context dictionary is passed to search() to set parameters like default_domain or custom flags. It’s often used in actions or wizards.
  • Use Case: Search partners with a context-based filter for a specific category.

Example:

# Set context to filter by category
self = self.with_context(category_filter='gold')
partners = self.env['custom.partner'].search([])
# In the model, override search with context
@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)

Frontend: Apply context 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>

Explanation: The context dynamically adds a filter to the search, reducing code duplication.

Search with Read Group

The read_group() method aggregates records by fields, useful for reports or grouped views.

  • How It Works: It groups records by specified fields, applies a domain, and computes aggregates (e.g., count, sum). Returns a list of dictionaries with grouped data.
  • Use Case: Group partners by category and count them.

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']}")

Explanation: This groups active partners by category, counting records and summing sales_count per group.

Searching records in Odoo 19 is a powerful skill that unlocks efficient data retrieval and reporting. From basic domains to advanced read_group() aggregations, these techniques enable developers to build dynamic, user-friendly applications. Experiment with these methods in a development environment. With Odoo 19’s AI integrations and optimized queries, your searches can be both powerful and intuitive.

To read more about How to Create Record Rules in Odoo 18, refer to our blog How to Create Record Rules in Odoo 18.


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
Kakkancherry, 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