2017-07-05 12 views
0

フォームの中にあるテーブルで作業しています。そのテーブルは、ユーザーが行う必要がある最初のフィールドの入力で自動的に埋められます。テーブルには、ユーザーがデータを入力する必要がある唯一の列があり、新しいフォームを開くのではなく、テーブルに直接データを入力できるようにしました。 これらのデータは、表に隠れた値を使ってチェックする必要があります。ユーザーが入力した値が許容範囲内であるかどうかを確認するだけです。Odoo 10 - 保存後に実際の行や関数を呼び出す

私の問題は、値を確認するために値のIDを知る必要がありますが、権限の許容値で確認できるようになっていますが、ユーザーがフォームを保存しないと取得できません。

私には2つの質問があります: 保存直後に関数を呼び出すことはできますか?私は "作成"関数をオーバーライドすることができますが、それは私が欲しいものではないことを知っている、私はIDを知ることができ、値をチェックすることが可能になりますので、保存直後に関数を呼び出す。 これが可能でない場合、私の2番目の質問は次のとおりです。 ユーザーが値を入力したときに行番号を取得できますか? api.onchangeで行番号を取得すると便利です。右の列を見つけてそこにあるデータを使用するまで、単純に行にループすることができます。お時間

EDIT1ため

ありがとう:ここで私は件のデータをループに行われたコード:

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 

ここでは、全体のコードは、私が方法がわからないというループを除いて、私がしたいどのように動作します適切に行うために、テストされているデータが正しいものであるかどうかを確認しました。テスト自体は必要に応じて機能しますが、毎回すべての行と最後をチェックしています。 その理由は、ユーザーがクリックした行番号を取得するというアイデアがあったのですが、それを実行することが可能かどうかわかりませんし、保存後に関数を呼び出すこともできません。保存後のデータ

答えて

0

2つの解決策は、私の心に来る:

  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')) 
    

の違いは、「保存」ボタンを押します後、それが呼び出されるということですが、実際にcreateまたはwrite機能を実行する前に。

希望、それは役に立ちます。

UPDATE 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

私はまだその実際に、多分私はそれがどのように動作するかよく理解していないとの問題を抱えているが、私はあなたの最初のソリューションを取る場合、私は複数のレコードをループする必要があると私は私のテストをします私はエラーを起こすことはありませんが、私は別のフィールドをfalseまたはtrueに設定し、falseの場合は行全体が赤くなり、それが私の問題です。 最後の値だけが考慮されていますが、自分の投稿を編集して、私が実際にやっていることを理解できるようにしました。 – Isariamkia

+0

私の答えが更新されました。 – tidylobster

+0

助けてくれてありがとう!私はそれを行うためにキャッシュを使用できるかどうかわからなかった! これでテストは正しく行われますが、保存すると有効なフィールドの値が正しく保存されません。テストの後にフィールドの値を表示するとTrueを表示しますが、保存するとFalseになりますデフォルト – Isariamkia

関連する問題