
本教程详细介绍了如何在odoo中为产品变体(`product.product`)列表视图添加基于产品模板(`product.template`)字段的自定义搜索功能。文章将引导读者通过定义关联字段、修改搜索视图xml,并重点强调使用`filter_domain`而非`domain`属性来正确构建搜索逻辑,从而解决常见的跨模型搜索难题。
在Odoo的开发实践中,经常需要扩展现有模型的功能,例如为产品变体(product.product)添加基于其所属产品模板(product.template)字段的搜索能力。直接在product.product的搜索视图中引用product.template上的字段会遇到问题,因为搜索字段的domain属性处理方式与预期不同。本教程将详细阐述如何正确实现这一功能。
1. 扩展产品模板模型
首先,我们需要在product.template模型中添加一个自定义字段。例如,我们添加一个名为model_number的字符型字段来存储产品型号。
from odoo import fields, models class ProductTemplate(models.Model): _inherit = 'product.template' model_number = fields.Char(String='型号', required=True)
这段代码通过继承product.template模型,引入了一个新的必填字符型字段model_number。
2. 在产品变体模型中创建关联字段
为了让product.product模型能够直接访问product.template上的model_number字段,我们需要在product.product模型中定义一个关联字段。这个关联字段将通过product_tmpl_id(product.product到product.template的Many2one字段)来获取model_number。
from odoo import fields, models class ProductProduct(models.Model): _inherit = 'product.product' model_number_search = fields.Char( string='产品型号', related='product_tmpl_id.model_number', store=True, # 设置store=True可以提高搜索性能,因为它会在数据库中存储该字段的值 readonly=True # 关联字段通常设置为只读 )
这里,model_number_search字段通过related属性关联到product_tmpl_id.model_number。store=True的设置非常重要,因为它会使这个关联字段的值实际存储在product.product表中,从而允许数据库对其进行索引和高效搜索。
3. 修改产品变体搜索视图
现在,我们可以在product.product的搜索视图中添加一个字段,用于搜索model_number_search。关键在于使用filter_domain属性而不是domain。
<?xml version="1.0" encoding="utf-8"?> <odoo> <record id="product_product_search_form_view_inherit" model="ir.ui.view"> <field name="name">product.product.search.form.view.inherit</field> <field name="model">product.product</field> <field name="inherit_id" ref="product.product_search_form_view"/> <field name="arch" type="xml"> <xpath expr="//field[@name='name']" position="after"> <field name="model_number_search" string="型号" filter_domain="[('model_number_search', 'ilike', self)]"/> </xpath> </field> </record> </odoo>
在这段XML代码中:
- 我们通过inherit_id继承了Odoo默认的product.product_search_form_view。
- xpath表达式用于在现有name字段之后插入我们的自定义搜索字段。
- 新添加的field名为model_number_search,其string属性定义了在搜索框中显示的标签。
- 核心改动: filter_domain=”[(‘model_number_search’, ‘ilike’, self)]”。这里使用了filter_domain属性,而不是domain。当用户在搜索框中输入内容时,self会代表用户输入的值,filter_domain会根据这个值构建实际的搜索条件,并应用于product.product模型上的model_number_search字段。
4. filter_domain与domain的区别
理解filter_domain和domain的区别是解决此类问题的关键:
- domain属性: 主要用于定义字段的可选值范围,或者在视图中对记录集进行静态过滤。当应用于field标签时,它通常限制该字段能显示哪些值,或在关联字段的下拉列表中过滤选项。
- filter_domain属性: 专为搜索视图中的field标签设计。它的作用是根据用户在搜索框中输入的值,动态地构建一个搜索域(domain),并将其应用到当前模型上。self关键字在filter_domain中代表用户输入的搜索值。
错误的尝试通常是使用domain=”[(‘product_tmpl_id.model_number’, ‘ilike’, self)]”。这会导致错误,因为domain属性在搜索字段中不能直接用于动态构建跨模型的搜索条件,特别是当字段本身不是关系字段时。filter_domain才是处理这种情况的正确机制。
5. 总结与注意事项
通过以上步骤,您已经成功地为Odoo的产品变体列表视图添加了基于产品模板字段的自定义搜索功能。
关键要点回顾:
- 扩展product.template: 添加您需要的自定义字段。
- 在product.product中创建关联字段: 使用related属性将product.template上的字段映射到product.product上,并设置store=True以优化搜索性能。
- 修改搜索视图: 在product.product的搜索视图中添加新的field,并务必使用filter_domain属性来定义搜索逻辑,其中self代表用户输入的值。
- 理解filter_domain: 它是专门用于搜索视图字段的动态域构建机制,与普通domain的用途不同。
完成代码修改后,请确保升级您的Odoo模块,以便数据库结构和视图定义能够正确更新。这样,用户就能在产品变体界面通过型号字段进行高效搜索了。