Not getting records which created in One2many field on onchange in transient model

2k Views Asked by At

I am trying to create records in one2many field in one of my transient model on onchange of boolean field.

Eg.

Models

class test_model(models.TransientModel):
    _name ="test.model"

    is_okay = fields.Boolean("Okay?")
    lines = fields.One2many("opposite.model","test_id",string="Lines")

    @api.onchange('is_okay')
    def onchnage_is_okay(self):
        ids = []
        for l in range(5):
            record = self.env['opposite.model'].create({'name':str(l),'test_id':self.id})
            ids.append(record.id)
        self.lines = [(6,0,ids)]



class opposite_model(models.TransientModel):
    _name ="opposite.model"

    name = fields.Char("Name")
    test_id = fields.Many2one("test.model",string="Test Model")

View

<record id="view_form" model="ir.ui.view">
    <field name="name">view.form</field> 
    <field name="model">test.model</field>
    <field name="type">form</field>
    <field name="arch" type="xml">
        <form string="Test Model">
           <field name="is_okay" />
           <field name="lines" />
           <footer>
            <button name ="click_okay" string="Okay" type="object"/>
           </footer>
       </form>
   </field>
</record>

Now, problem is that when in check or uncheck the is_okay field it fills the records in the One2many field.

That is working fine.

But in my above view i have button which calls the method click_okay().

Eg.

@api.one
def click_okay(self):
    print self.lines

So, print statement gives me blank recordset. But, i can see the 5 records in the view when i am changing is_okay field.

I am not getting any idea how to get those lines in method?

Any response would be appreciated?

2

There are 2 best solutions below

1
On

It should work. That's wired behavior.

You may try with following alternative way using self.update()

@api.onchange('is_okay')
def onchnage_is_okay(self):
    ids = []
    for l in range(5):
        record = self.env['opposite.model'].create({'name':str(l),'test_id':self.id})
        ids.append(record.id)
    self.update({
        'lines' : [(6,0,ids)]
    )}
1
On

No matter what odoo keep doing the same thing:

the problem is that odoo always passes this records to create method with command 1 but in odoo we cannot use this command in create method and this why you lose this records in the call of method.

(1, id, values) updates an existing record of id id with the values in values. Can not be used in create().

i don't know why you are creating this record in onchange event because this not recomanded if the user hit close instead of ok the record all ready created in database and every time he check the button will recreate this record again and again.

if you don't need to create this records in the onchange event what you should do is:

@api.onchange('is_okay')
def onchnage_is_okay(self):
    ids = []
    for l in range(5):
        record = self.env['opposite.model'].new({'name': str(l)})
        ids.append(record.id)
    self.lines = ids

one thing here onchange will return the dictionnary to the form, the tree of the one2field must have all field that are passed in that dictionary in this case the tree must have field name if oppisite.model have for example another field like test_field if we pass {'name': value, 'test_field': value_2} if the tree have only name field value of test_field will be lost in create method.

but if you need like you are doing, you should work arround odoo and change the command to 4 in create a method:

@api.model
def create(self, vals):
    """
    """
    lines = vals.get('lines', False)
    if lines:
        for line in lines:
            line[0] = 4
            line[2] = False
    vals.update({'lines': lines})
    return super(test_model, self).create(vals)