在Odoo 8中,是否有一种在创建或写入时标准化字段值的首选方法?我想到了几种方法,但这个功能似乎属于API。本质上,我想创建一个指定标准化函数的字段,有点像只指定反函数的计算字段。这是否已存在于API的某个位置?
方法0:创建一个指定标准化函数的字段。
我能用这种方法看到的唯一缺陷就是API不存在。
import openerp
class Model(openerp.models.Model):
_name = 'addon.model'
field = openerp.fields.Text(
required=True,
standardize='_standardize_field',
)
@openerp.api.one
def _standardize_field(self):
self.field = self.field.upper()
方法1:覆盖create和write方法以插入调用以标准化字段。
这是有效的,但对于上面的单个函数可以做什么似乎相当冗长。请注意,如果required=True
且标准化可能产生空字段,则需要约束。
import openerp
class Model(openerp.models.Model):
_name = 'addon.model'
field = openerp.fields.Text(
required=True,
)
@openerp.api.one
@openerp.api.constrains('field')
def _constrains_field(self):
if len(self.field) == 0:
raise openerp.exceptions.ValidationError('Field must be valid.')
def _standardize(self, args):
if 'field' in args:
# Return standardized field or empty string.
args['field'] = args['field'].upper()
@openerp.api.model
def create(self, args):
self._standardize(args)
return super(Model, self).create(args)
@openerp.api.multi
def write(self, args):
self._standardize(args)
super(Model, self).write(args)
return True
方法2:使用计算字段和一些魔法。
这有效,但感觉有点做作。此外,此方法要求标准化函数是确定性的,否则可能会产生无限循环。请注意,标准化功能可能会被调用两次,如果标准化是一项昂贵的操作,这可能是一个问题。
import openerp
class Model(openerp.models.Model):
_name = 'addon.model'
field = openerp.fields.Text(
compute=lambda x: x,
inverse='_inverse_field',
required=True,
store=True,
)
@openerp.api.one
@openerp.api.constrains('field')
def _constrains_field(self):
if self._standardize_field() is None:
raise openerp.exceptions.ValidationError('Field must be valid.')
def _inverse_field(self):
field = self._standardize_field()
# If the field is updated during standardization, this function will
# run a second time, so use this check to prevent an infinite loop.
if self.field != field:
self.field = field
def _standardize_field(self):
# Return the standardized field.
return self.field.upper()
方法3:使用常规字段和计算字段,仅在视图中公开计算字段。
readonly标志和约束有助于保护底层字段,但我不确定这种方法是否能保持数据的完整性,整个方法感觉很人为。
import openerp
class Model(openerp.models.Model):
_name = 'addon.model'
field = openerp.fields.Text(
readonly=True,
required=True,
)
field_for_view = openerp.fields.Text(
compute='_compute_field_for_view',
inverse='_inverse_field_for_view',
required=True,
)
@openerp.api.one
@openerp.api.depends('field')
def _compute_field_for_view(self):
self.field_for_view = self.field
@openerp.api.one
@openerp.api.constrains('field', 'field_for_view')
def _constrains_field(self):
if self._standardize_field() is None:
raise openerp.exceptions.ValidationError('Field must be valid.')
def _inverse_field(self):
self.field = self._standardize_field()
def _standardize_field(self):
# Return the standardized field.
return self.field_for_view.upper()
答案 0 :(得分:0)
也许'默认'属性是你的方法#1的实现? 以下是https://www.odoo.com/documentation/8.0/reference/orm.html#creating-models
中Odoo8文档中的示例a_field = fields.Char(default=compute_default_value)
def compute_default_value(self):
return self.get_value()
另一种选择是覆盖子类中的write()
方法以添加您的调用,如下所示:
def write(self, vals):
for record in self:
# do the cleanup here for each record, storing the result in
# vals again
# call the super:
res = super(extendedProject, self).write(vals)
return res
vals
是一个包含要存储的修改值的字典; self
是一个记录集,包含存储值的所有记录。请注意,从您致电write
返回后,Odoo中的交易仍可能会回滚。