悠悠楠杉
网站页面
正文:
在Odoo的电商或库存管理场景中,产品变体(Product Variant)的搜索功能直接影响用户体验。系统默认的搜索逻辑仅覆盖基础字段(如名称、内部编码),但实际业务中常需通过自定义字段快速定位产品。本文将手把手教你扩展搜索功能,使其支持产品模板(Product Template)的自定义字段。
Odoo的搜索功能依赖_search方法和name_search的默认实现,但二者均未主动关联产品模板的自定义字段。例如,若产品模板添加了“环保等级”字段,用户无法直接通过该字段筛选变体。
解决思路分为三步:
1. 扩展产品变体模型:建立变体与模板自定义字段的关联
2. 重写搜索逻辑:将自定义字段纳入搜索域
3. 优化查询性能:避免N+1查询问题
首先在product.product(变体模型)中添加计算字段,将模板字段“透传”给变体:
from odoo import models, fields, api
class ProductProduct(models.Model):
_inherit = 'product.product'
custom_field_proxy = fields.Char(
string="模板字段代理",
compute='_compute_custom_field_proxy',
store=False # 非存储字段,实时计算
)
@api.depends('product_tmpl_id')
def _compute_custom_field_proxy(self):
for variant in self:
# 假设模板有个名为eco_level的自定义字段
variant.custom_field_proxy = variant.product_tmpl_id.eco_level
通过重写_search方法,将自定义字段加入搜索条件:
def _search(self, domain, *args, **kwargs):
# 解析原始domain,替换自定义字段标记
new_domain = []
for item in domain:
if isinstance(item, (list, tuple)) and item[0] == 'custom_field_proxy':
# 转换为对模板字段的搜索条件
new_domain.append(('product_tmpl_id.eco_level', item[1], item[2]))
else:
new_domain.append(item)
return super(ProductProduct, self)._search(new_domain, *args, **kwargs)
sql
CREATE INDEX eco_level_idx ON product_template (eco_level);
self = self.with_context(prefetch_fields=True)
为了让搜索框支持自定义字段提示,需扩展name_search:
def name_search(self, name='', args=None, operator='ilike', limit=100):
if args is None:
args = []
# 添加对代理字段的搜索支持
args.extend(['|', ('custom_field_proxy', operator, name)])
return super().name_search(name, args, operator, limit)
python
self.env.cr._obj.logger.debug("Search query: %s", self._where_calc(domain))通过以上步骤,用户现在可以在产品变体搜索框中直接输入“环保等级A+”等自定义字段内容,系统将自动返回匹配的变体列表。此方案保持了Odoo原生搜索的灵活性,同时满足了业务定制化需求。