2017-07-05 53 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