How to Add a Search Filter for Computed Fields in Odoo 18
By Braincuber Team
Published on February 12, 2026
Computed fields in Odoo are incredibly powerful for displaying dynamic data calculated on the fly. However, developers often hit a roadblock: Search errors. Because non-stored computed fields don't exist in the database, trying to filter by them usually results in a crash or a silent failure.
The solution isn't always to set store=True, which can bloat your database and cause recalculation overhead. The elegant solution is the search= parameter. In this tutorial, we'll implement a custom search filter for a Fleet Management system to find vehicles with "Expired Warranties" without storing the computed status.
The Problem
- Non-Stored Fields: Only exist in Python memory (RAM), not SQL tables.
- SQL WHERE Clause: Cannot reference a column that doesn't exist.
- The Fix: We must tell Odoo how to "translate" our search into a valid SQL domain.
Step 1: Define the Field with a Search Method
We have a field warranty_expiry_date (which is stored). We want a boolean computed field is_warranty_expired.
from odoo import models, fields, api
from datetime import date
class FleetVehicle(models.Model):
_inherit = 'fleet.vehicle'
warranty_expiry_date = fields.Date(string="Warranty Expiry")
# 1. Add the search='_search_expiry' argument
is_warranty_expired = fields.Boolean(
string="Warranty Expired",
compute='_compute_warranty_expired',
search='_search_warranty_expired'
)
@api.depends('warranty_expiry_date')
def _compute_warranty_expired(self):
for record in self:
if record.warranty_expiry_date:
record.is_warranty_expired = record.warranty_expiry_date < date.today()
else:
record.is_warranty_expired = False
Step 2: Implement the Search Logic
Now we implement the search method. This method receives the search operator and value (e.g., '=', True) and must return an Odoo domain that filters the records using stored fields.
def _search_warranty_expired(self, operator, value):
# We want to find vehicles where warranty < today
today = fields.Date.today()
# Logic: If user searches "Expired is True"
if (operator == '=' and value is True) or (operator == '!=' and value is False):
return [('warranty_expiry_date', '<', today)]
# Logic: If user searches "Expired is False" (Valid Warranty)
elif (operator == '=' and value is False) or (operator == '!=' and value is True):
return [('warranty_expiry_date', '>=', today)]
# Default fallback (should not ideally happen with boolean toggle)
return []
Step 3: Add the Filter to XML
With the backend logic ready, we can now add a simple filter to our XML search view. Odoo will automatically route this filter through our _search_warranty_expired method.
fleet.vehicle.search.inherit
fleet.vehicle
Conclusion
The search= parameter allows you to harness the best of both worlds: the dynamic flexibility of computed fields and the performance of database-level filtering. By mapping your computed concepts to stored field domains, you keep your Odoo system fast and your code clean.
Master Odoo Development?
Avoid common pitfalls and build scalable Odoo apps. Our expert team offers code reviews and architectural consulting.
