如何在Odoo 8中创建或写入时标准化字段值?

时间:2015-10-09 00:05:34

标签: odoo odoo-8

在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()

1 个答案:

答案 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中的交易仍可能会回滚。