Skip to Content
Menu
You need to be registered to interact with the community.
This question has been flagged

As described here onchange methods are called with virtual recordset by Odoo, if a corresponding field is changed. Say I have the following onchange method:

@api.onchange('my_field')
def onchange_my_field(self):
pass

when Odoo calls this method internally, the "self" is a virtual recordset. However, I have a scenario where I would like to call this method manually, from the another object method, where I do NOT have virtual recordset, but a normal recordset instead, so if I call the onchange method like this:

self.onchange_my_field()

it gets called with ordinary recordset instead of virtual recordset (consequently the final result is as expected, except of huge difference in performance).


In order to avoid the performance penalty, I would like to get somehow virtual recordset from the ordinary "self" recordset I have for the moment and than call the onchange function using it. i.e. something like:

rec = get virtual recordset from self
rec.onchange_my_field()

it comes down to the question: How to get a virtual record/recordset from an ordinary record/recordset?

Avatar
Opusti
Best Answer

Hi Temur

You could do it using the "new" method like this:

invoice_id = self.env['account.invoice'].new(vals)
invoice_id._onchange_partner_id()
invoice_vals = invoice_id._convert_to_write(invoice_id._cache)

Where vals is a normal dict of vals for the virtual record and invoice_vals will have the resulting virtual record modifications made by the onchange call. If you don't have the vals and you need to pass all the vals from a record you could use the method copy_data to get it by it's id like:

#from a recordset one record
vals = self.copy_data()
#from a record by id
vals = self.browse(id).copy_data()

also the copy_data method accept an optional dict argument with the default data for the result dict


UPDATE (Temur):

before calling "new" method,

if type(vals) == list:
vals = vals[0]

-see comment below.

Avatar
Opusti
Avtor

Thanks Axel for your reply. I tried it and a code "vals = self.copy_data()" followed by "self.env['some.model'].new(vals)" gave me an error. I'll investigate the error deeper as soon as I'll have some spare time. I forgot to mention in my question that server used is a v9, should it work in v9 as well? Or you were referring to a different version?

That is the way of the new api, no matter what version you are using, v8, v9, v10 or master.

Avtor

It seems `new` method expects a dictionary, whereas `copy_data` method returns a list of dictionaries. I fixed the error by using `vals = self.copy_data()[0]` instead of `vals = self.copy_data()` and so I was able to get a virtual record.

Related Posts Odgovori Prikazi Aktivnost
1
okt. 23
2114
2
okt. 23
2362
2
avg. 23
4405
4
avg. 23
20756
3
okt. 22
11177