T.Nel T.Nel - 6 months ago 392
Python Question

Odoo : Acces a column from many2one

Here is my problem :

I'm in model1 :

class model1(osv.osv):
_name = 'model1'
_columns = {
'name': fields.many2one('res.partner',
u'Person',
domain=[('my_boolean', '=', False)],
required=True,
select=True),
'type' = fields.selection([('1', 'One'),
('2', 'Two'),
u'Select',
required=True),
}

@api.onchange('type')
def onchange_type_model1(self)
self.name.model3_id = 2


And I want to modify in this onchange the value of the id of model3_id in res.partner:

-res.partner in this module:

class res_partner(osv.osv):
_inherit = 'res.partner'
_columns = {
'model1_partner_ids': fields.one2many('model1',
'name',
u'asker from model1',
select=True),
}


-res.partner in the module with model3:

class res_partner:
_inherit = res.partner
_columns = {
'model3_id': fields.many2one('model3',
u'Model3'
track_visibility='onchange',
select=True),
}


model3 is not important here, I have 10 id of model3 objects and I need to be able to affect, for example, the id " 2 " to 'model3_id' in res.partner when "type" is modified in model1.

I tried this : odoo - get value from many2one field by doing this:

@api.onchange('type')
def onchange_type_demand(self, cr, uid, ids, context=None):
for name in self.browse(cr, uid, ids, context=context):
if name.model3_id:
name.model3_id = 2


But it give me an error saying that record.env doesn't exist. I tried to find answer to this error but none matched with my code.

I looked to dozens of topics, tried all the morning to fix it, but whatever I do, it won't works. (The first thing I did -appear in first class I wrote- didn't gave me any error but changed nothing in the database.)

Thanks for reading and for any help you could provide.

EDIT: I think the only real question here is "How to give an ID as a value for a many2one?" But I'm not sure that this is the only problem here so I let all the text.

Answer

I finally solved my problem :

When you create an onchange, it seams that it will only change the javascript, if the field you try to modify, thanks to an onchange on an other field, isn't in your tree, it won't be changed. What I figured out, doing some attempt while looking at phppgadmin:

  • When you change your field, it update the javascript, nothing is done in the database.
  • Once you saved your change, the javascript seams to analyse the fields and update the database with those.

So when something is not in the xml, you can't use onchange on it. It's a real pain if you want to change something in another model or module. But more of that it was really stupid to try this and it perfectly make sense: the purpose of onchange is to update before any registration is done, the only interest is to show it while your still modify it.

The solution was quite simple thanks to the Odoo 8.0 API. Here is an exemple (This is in res partner):

'my_field': field.many2one(compute='_compute_second_field', store=True, readonly=True)

@api.depends('name_ids.type') //name_ids is the one2many reverse of name's many2one in model1
for record in self:
    if self.name_ids://if some names are pointing to this, name_ids is not empty
        self.model3_id = 2
    else://if doesn't exist, default value 
        self.model3_id = 0

So when you create in res_partner, this res_partner is still not in model1, take value '0'. Then you add it in model1, take value 2. If you remove him from model1, take value '0' again (removing is still a modification).

for openerp-7 it is 'fields.function' (with type='many2one' as argument and store={('model1':_other_function, ['type'], 10)} but I didn't managed to finish it this way, so I won't show it