我如何通过 Odoo 中的计算字段进行搜索?
How can I search by a computed field in Odoo?
我正在尝试通过 Odoo 9 中的计算字段进行搜索。但它 return 全部记录为结果。
class Version(models.Model):
_name='product_cars_application.version'
name = fields.Char(compute="_get_name", store=True)
@api.one
def _get_name(self):
self.name = "%s %s %s (%s)" % (self.brand_id,
self.model_id.name,
self.vname,
self.year_id)
我试过使用 store=True
和不使用它,但是名称字段没有存储在数据库中。我还尝试从数据库中删除列 "name",然后我更新了模块,但它没有存储计算。计算字段在表单视图上工作正常,但名称未存储,搜索无效。
那么,如何通过字段名称进行搜索?
将此添加到您的代码中。
def _name_search(self,name, args=None, operator='ilike', limit=100):
if operator == 'like':
operator = 'ilike'
versions=self.search([('name', operator, name)], limit=limit)
return versions.name_get()
name = fields.Char(compute=_get_name, store=True,search=_name_search)
您可以在文档中查看详细信息。
https://www.odoo.com/documentation/8.0/reference/orm.html
第 "Computed Fields" 部分适合您。
希望它能奏效。让我知道。
我不建议您在计算字段中使用 store=True
如果它们不是完全必要的(如果您想要 group by
此字段则需要这样做)因为它们在某些方面效果不佳情况下,尽管最新版本效果更好。所以,我认为你可以这样做:
class Version(models.Model):
_name = 'product_cars_application.version'
name = fields.Char(
compute="_compute_name",
search="_search_name",
)
@api.one
def _compute_name(self):
self.name = "%s %s %s (%s)" % (self.brand_id,
self.model_id.name,
self.vname,
self.year_id)
def _search_name(self, operator, value):
""" Actually this converts a domain into another one.
With this new domain Odoo can search well
A list of ids is the most easy way without computed fields
* [('id', 'in', id_list)]
"""
if operator == 'ilike':
name = self.env.context.get('name', False)
if name is not False:
id_list = []
product_cars = self.env['product_cars_application.version'].search([])
for car in product_cars:
if name in car.name:
id_list.append(lot.id)
return [('id', 'in', lot_id_list)]
else:
return [('id', 'in', [])]
else:
_logger.error(
'The field name is not searchable'
' with the operator: {}',format(operator)
)
考虑到这种搜索方式比将值存储在数据库中效率低,因为您总是必须遍历所有记录来计算值。
顺便说一句,对于您的特定使用情况,您可以做的最好的事情是将字段名称创建为普通字符,而不是计算。您可以设置默认值来创建名称。这样,值将被存储,问题将消失。
我正在尝试通过 Odoo 9 中的计算字段进行搜索。但它 return 全部记录为结果。
class Version(models.Model):
_name='product_cars_application.version'
name = fields.Char(compute="_get_name", store=True)
@api.one
def _get_name(self):
self.name = "%s %s %s (%s)" % (self.brand_id,
self.model_id.name,
self.vname,
self.year_id)
我试过使用 store=True
和不使用它,但是名称字段没有存储在数据库中。我还尝试从数据库中删除列 "name",然后我更新了模块,但它没有存储计算。计算字段在表单视图上工作正常,但名称未存储,搜索无效。
那么,如何通过字段名称进行搜索?
将此添加到您的代码中。
def _name_search(self,name, args=None, operator='ilike', limit=100):
if operator == 'like':
operator = 'ilike'
versions=self.search([('name', operator, name)], limit=limit)
return versions.name_get()
name = fields.Char(compute=_get_name, store=True,search=_name_search)
您可以在文档中查看详细信息。
https://www.odoo.com/documentation/8.0/reference/orm.html
第 "Computed Fields" 部分适合您。
希望它能奏效。让我知道。
我不建议您在计算字段中使用 store=True
如果它们不是完全必要的(如果您想要 group by
此字段则需要这样做)因为它们在某些方面效果不佳情况下,尽管最新版本效果更好。所以,我认为你可以这样做:
class Version(models.Model):
_name = 'product_cars_application.version'
name = fields.Char(
compute="_compute_name",
search="_search_name",
)
@api.one
def _compute_name(self):
self.name = "%s %s %s (%s)" % (self.brand_id,
self.model_id.name,
self.vname,
self.year_id)
def _search_name(self, operator, value):
""" Actually this converts a domain into another one.
With this new domain Odoo can search well
A list of ids is the most easy way without computed fields
* [('id', 'in', id_list)]
"""
if operator == 'ilike':
name = self.env.context.get('name', False)
if name is not False:
id_list = []
product_cars = self.env['product_cars_application.version'].search([])
for car in product_cars:
if name in car.name:
id_list.append(lot.id)
return [('id', 'in', lot_id_list)]
else:
return [('id', 'in', [])]
else:
_logger.error(
'The field name is not searchable'
' with the operator: {}',format(operator)
)
考虑到这种搜索方式比将值存储在数据库中效率低,因为您总是必须遍历所有记录来计算值。
顺便说一句,对于您的特定使用情况,您可以做的最好的事情是将字段名称创建为普通字符,而不是计算。您可以设置默认值来创建名称。这样,值将被存储,问题将消失。