2017-07-05 59 views
0

我正在处理表单内的表格。该表格会自动填入用户必须执行的第一个字段的输入。在表格中,只有一列用户必须输入数据,我可以让他们直接在表格中输入数据,而不是打开新的表格。 这些数据需要使用隐藏在表格中的值进行检查,我只需检查用户输入的值是否符合某些公差。Odoo 10 - 保存后获取实际的行或调用函数

现在我的问题是,为了检查值我需要知道的值的ID可以检查与权限公差,但我不能让他们,如果用户不保存表格。

所以我有两个问题: 是否可以在保存后调用一个函数?我知道我可以重写“创建”函数,但这不是我想要的,我想要一个函数在保存后立即调用,这要感谢我能够知道ID并且可以检查这些值。 如果这是不可能的,我的第二个问题是: 当用户输入其值时可以获取行号吗?用api.onchange获取行号是很有用的,这样我可以简单地循环到行中,直到找到合适的行,然后使用那里的数据。

感谢您的时间

EDIT1:在这里,我通过DATAS循环使代码:

class ControlMeasure(models.Model): 
    """ 
     Modèle pour la mesure d'une pièce 
    """ 

# Nom de la table 
_name = 'spc.control.measure' 

# Champs de la table 
name    = fields.Many2one(string='Name', related='control_point_id.measure_type_id', readonly=True) 
value    = fields.Float(string='Measured value') 
validity   = fields.Boolean(string='Validity', readonly=True) 
nominal_value  = fields.Float(string='Nominal value', related='control_point_id.nominal_value', readonly=True) 

unit_id    = fields.Many2one('product.uom', string='Unit', related='control_point_id.product_uom_id', readonly=True)    
control_part_id  = fields.Many2one('spc.control.part', string='Controled piece') 
control_point_id = fields.Many2one('spc.control.point', string='Control point') 

# Champs visuels 
control_device_id = fields.Many2one('spc.control.device', string='Used device', related='control_point_id.control_device_id') 

# Vérifie si la valeur mesurée est dans la tolérance 
@api.multi 
@api.onchange('value') 
def is_valid(self): 

    # raise Exception('Appel réussi') 

    sql= """ 
      SELECT p.nominal_value, p.inferior_tolerance, p.superior_tolerance FROM spc_control_point p 
      WHERE p.control_plan_id = %(ctrlid)s 
     """ 

    if self.control_part_id.control_plan_id == False: 
     raise Exception('False ' + str(self.control_part_id.control_plan_id)) 
    else: 
     self.env.cr.execute(sql, {'ctrlid' : self.control_part_id.control_plan_id.id}) 
     row = self.env.cr.fetchall() 

     for i in range(0, len(row)): 
      #raise Exception(str(self.value) + ' < ' + str(row[i][0]) + ' - ' + str(abs(row[i][1])) + ' or ' + str(self.value) + ' > ' + str(row[i][0]) + ' + ' + str(abs(row[i][2]))) 
      if self.value < row[i][0] - abs(row[i][1]) or self.value > row[i][0] + abs(row[i][2]): 
       self.validity = False 
      else: 
       self.validity = True 

在这里,整个代码工作我多么希望,只是我不知道该怎么循环为了做到这一点,我检查了被测试的数据是否正确,测试本身是否正常工作,但每当我查看所有行和结尾时,只看到最后一个数。 这就是为什么我想出了用户点击行号的想法,但我不知道是否可以做到这一点,甚至在保存后调用函数是很容易的,因为我会知道这些ID,并且我可以检查保存后的数据。

回答

0

两个可能的解决方案上来在我的脑海:

  1. 正如你所说,你可以创建一个方法与@api.onchange装饰,检查输入数据,每次用户通过它,实际上并没有将其保存或任何其他操作。

    @api.multi 
    @api.onchange('your_field', 'your_field2') 
    def _onchange_your_fields(self): 
        for record in self: 
         if record.your_field != record.validation_field: 
          raise exceptions.ValidationError(_('Sorry, pal, try again')) 
    

关于这个的好处是,它会迅速验证字段的值:之后,用户就会把光标置于下一个字段。尽管如此,从用户的角度来看,这可能会令人恼火。

  1. 您可以尝试@api.constrains装饰器。它的表现与装饰器@api.onchange略有不同,但通常使用它来进行验证。

    @api.multi 
    @api.constrains('your_field', 'your_field2') 
    def _check_your_fields(self): 
        for record in self: 
         if record.your_field != record.validation_field: 
          raise exceptions.ValidationError(_('Sorry, pal, try again')) 
    

不同的是,它会被称为后,你会打“保存”按钮,但实际执行createwrite功能之前。

希望,这将有所帮助。

更新1:

# Vérifie si la valeur mesurée est dans la tolérance 
@api.multi 
@api.onchange('value') 
def validate(self): 
    # Because we are using @api.multi decorator, our 'self' is actually a recordset. 
    # That means, that we cannot treat it as a regular record, so "self.control_part_id...." would be an odd code 
    for record in self: 
     # So now we took a one record from recordset, and now we can continue on validating it. 
     if not record.control_part_id.control_plan_id: 
      raise exceptions.UserError(_('False %s' % str(record.control_part_id.control_plan_id))) 

     # You executed here a SQL query, which is actually takes our records from database, not from cache. 
     # But we haven't write(or create) our changes yet, and that makes no sense. 

     # What we wanna do, is to take values from cache and validate them. You can simply do it just via model's field 
     validation_record = record.control_point_id 

     if record.value < validation_row.nominal_value - validation_row.inferior_tolerance \ 
      or record.value > validation_row.nominal_value + validation_row.superior_tolerance: 
       record.validity = True 

     else: 
      # You can get rid of this line by simply defining the default value of record.validity as "False" 
      record.validity = False 


# I recommend you to check the final validation this way 
@api.multi 
@api.constrains('validity') 
def check_valid(self): 
    for record in self: 
     if not record.validity: 
      raise exceptions.ValidationError(_("Cannot pass a validation rest")) 
+0

我仍然有一个问题,实际上,也许我不理解以及它是如何工作,但如果我把你的第一个解决方案,我通过多个记录,并在需要循环我做我的测试我不提出一个错误,但我设置另一个字段为假或真,如果它是假的整行变红,这就是我的问题。 当我这样做时,只有最后一个值被考虑,我会编辑我的帖子,把我为你做的代码理解我在做什么 – Isariamkia

+0

我更新了我的答案,请检查出来。 – tidylobster

+0

感谢您的帮助!我不知道我可以使用缓存来做到这一点! 所以现在,它做了正确的测试,但是当我保存时,有效性字段的值没有正确保存,当我在测试后显示字段的值时,它显示True,但是当我保存它时,False通过False默认 – Isariamkia