Reputation: 1588
I have a computed field, that has to be updated when a field is updated.
So I use @api.depends('field1')
and link the function
field_to_compute: fields.integer(compute='the_function' store=True)
It works fine.
But know I'd like to update it when field1
take value A
and to remain the same when field1
take the value B
. But the old value of field_to_compute
was imported from a database and wasn't computed.
So I have two problems:
How can I make something like:
@api.depends('field1')
def the_function(self):
value = self.field1
if value == A:
field_to_compute = 123123
elif value == B:
field_to_compute = stored_field_to_compute #field_to_compute
keep the same value as the one stored before
EDIT (example):
I'm in a res.partner in the current model, inheriting of res.partner. I've a field in it :
'model_state': field.char(compute='compute_type', string = 'Demand', store=True, readonly=True)
In a second res.partner inheriting of res.partner too, in an other module, I have 2 fields : grade
and status
, respectively an int, and a many2one. Computing the same compute_type as model_state, the same way.
I also in this res.partner, have a one2many field : link_ids
So my function is :
@api.depends('link_ids.type', 'link_ids.result')
def compute_type(self):
for record in self:
if self.link_ids:
if self.link_ids.result == 'A':
if self.link_ids.type == 'type1':
record.model_state = 'Mytext'
record.grade = 15
record.state = 1 #this is an id
elif self.link_ids.result == 'B':
record.model_state = 'MySecondText'
record.state = 2 #this is an id
I won't put everything because it's like 25 elif (not all about the same if etc etc) so it wouldn't be pertinent. I checked a lot of time if nothing was modifying record.grade if nothing is done on it, in else or dunno, but it's just being emptied.
Basically, simplified, I'd like to do something if the result is "OK" to a vote. And change the id of the state to "accepted", give a text (like a title), and give him a better grade, and if it's not, he have an id of the state "denied", give an other text, and keep the same grade as he has actually.
Upvotes: 2
Views: 11498
Reputation: 11
For the computed fields that needs to save its value on DB table, we use the "@api..depends('field_attributes')" decorator, that when there were a change made to the defined fields attributes, it will trigger to execute the Function.
For the computed fields that don't need to have saved its value on DB table, we do not need anymore this "@api..depends('field_attributes')", Reloading the form would serve as a trigger for the function's execution. But the disadvantage for this is, we won't be able to search a data from this certain field.
Upvotes: 0
Reputation: 14768
Do a prefetch by yourself (field_to_compute has to be stored):
@api.multi
@api.depends('field_x')
def _compute_field_to_compute(self):
# prefetch
data = {d['id']: d['field_to_compute']
for d in self.read(['field_to_compute'])}
for record in self:
if record.field_x == '123456':
record.field_to_compute = '654321'
else:
record.field_to_compute = data.get(record.id, 'default')
Upvotes: 4
Reputation: 14746
You should try following,
@api.onchange('field1')
def function(self):
field_value = self.field_to_compute
if self.field1 == A:
field_value = 123123
self.field_to_compute = field_value
Upvotes: 1
Reputation: 1162
Try with:
@api.onchange('field1')
def function(self)
if value == A:
field_to_compute = 123123
elif value == B:
field_to_compute = stored_field_to_compute #field_to_compute keep the same value as the one stored before
Upvotes: 0
Reputation: 2431
if the value is B just don't do anything... or better: set the field value only when needed. Something like:
def _compute_foo(self):
for item in self:
if item.other_field != B:
item.foo = 'newvalue'
I think you problem is that you are not setting the value as you should do for computed fields (see item.foo = 'newvalue'
).
Take a look at official docs.
Upvotes: 1