[FIX] models: recompute nested old-style computed field
The `set` method of the one2many class returns a list of the fields that require recomputation, the computing of the function fields being delayed for performances reasons. Nevertheless, if the `set` method was called through another `set` method, in other words, nested `set` calls, the fields to recompute returned by the second, nested, call to set were never recomputed, the result list were simply lost. e.g.: ``` create/write │set └─── create/write with recs.env.recompute set to False │set └─── create with recs.env.recompute set to False ``` To overcome this problem, the list of old api style compute fields to recompute is stored within the environment, and this list is cleared each time the store_set_value has done its job of recomputing all old api style compute fields. opw-629650 opw-632624 closes #6053
This commit is contained in:
parent
6553eb3742
commit
b7f1b9c01e
|
@ -907,6 +907,13 @@ class Environment(object):
|
||||||
finally:
|
finally:
|
||||||
self.all.recompute = tmp
|
self.all.recompute = tmp
|
||||||
|
|
||||||
|
@property
|
||||||
|
def recompute_old(self):
|
||||||
|
return self.all.recompute_old
|
||||||
|
|
||||||
|
def clear_recompute_old(self):
|
||||||
|
del self.all.recompute_old[:]
|
||||||
|
|
||||||
|
|
||||||
class Environments(object):
|
class Environments(object):
|
||||||
""" A common object for all environments in a request. """
|
""" A common object for all environments in a request. """
|
||||||
|
@ -915,6 +922,7 @@ class Environments(object):
|
||||||
self.todo = {} # recomputations {field: [records]}
|
self.todo = {} # recomputations {field: [records]}
|
||||||
self.mode = False # flag for draft/onchange
|
self.mode = False # flag for draft/onchange
|
||||||
self.recompute = True
|
self.recompute = True
|
||||||
|
self.recompute_old = [] # list of old api compute fields to recompute
|
||||||
|
|
||||||
def add(self, env):
|
def add(self, env):
|
||||||
""" Add the environment `env`. """
|
""" Add the environment `env`. """
|
||||||
|
|
|
@ -3994,10 +3994,10 @@ class BaseModel(object):
|
||||||
recs.invalidate_cache(['parent_left', 'parent_right'])
|
recs.invalidate_cache(['parent_left', 'parent_right'])
|
||||||
|
|
||||||
result += self._store_get_values(cr, user, ids, vals.keys(), context)
|
result += self._store_get_values(cr, user, ids, vals.keys(), context)
|
||||||
result.sort()
|
|
||||||
|
|
||||||
done = {}
|
done = {}
|
||||||
for order, model_name, ids_to_update, fields_to_recompute in result:
|
recs.env.recompute_old.extend(result)
|
||||||
|
for order, model_name, ids_to_update, fields_to_recompute in sorted(recs.env.recompute_old):
|
||||||
key = (model_name, tuple(fields_to_recompute))
|
key = (model_name, tuple(fields_to_recompute))
|
||||||
done.setdefault(key, {})
|
done.setdefault(key, {})
|
||||||
# avoid to do several times the same computation
|
# avoid to do several times the same computation
|
||||||
|
@ -4008,6 +4008,7 @@ class BaseModel(object):
|
||||||
if id not in deleted_related[model_name]:
|
if id not in deleted_related[model_name]:
|
||||||
todo.append(id)
|
todo.append(id)
|
||||||
self.pool[model_name]._store_set_values(cr, user, todo, fields_to_recompute, context)
|
self.pool[model_name]._store_set_values(cr, user, todo, fields_to_recompute, context)
|
||||||
|
recs.env.clear_recompute_old()
|
||||||
|
|
||||||
# recompute new-style fields
|
# recompute new-style fields
|
||||||
if recs.env.recompute and context.get('recompute', True):
|
if recs.env.recompute and context.get('recompute', True):
|
||||||
|
@ -4257,16 +4258,18 @@ class BaseModel(object):
|
||||||
# check Python constraints
|
# check Python constraints
|
||||||
recs._validate_fields(vals)
|
recs._validate_fields(vals)
|
||||||
|
|
||||||
if recs.env.recompute and context.get('recompute', True):
|
result += self._store_get_values(cr, user, [id_new],
|
||||||
result += self._store_get_values(cr, user, [id_new],
|
|
||||||
list(set(vals.keys() + self._inherits.values())),
|
list(set(vals.keys() + self._inherits.values())),
|
||||||
context)
|
context)
|
||||||
result.sort()
|
recs.env.recompute_old.extend(result)
|
||||||
|
|
||||||
|
if recs.env.recompute and context.get('recompute', True):
|
||||||
done = []
|
done = []
|
||||||
for order, model_name, ids, fields2 in result:
|
for order, model_name, ids, fields2 in sorted(recs.env.recompute_old):
|
||||||
if not (model_name, ids, fields2) in done:
|
if not (model_name, ids, fields2) in done:
|
||||||
self.pool[model_name]._store_set_values(cr, user, ids, fields2, context)
|
self.pool[model_name]._store_set_values(cr, user, ids, fields2, context)
|
||||||
done.append((model_name, ids, fields2))
|
done.append((model_name, ids, fields2))
|
||||||
|
recs.env.clear_recompute_old()
|
||||||
# recompute new-style fields
|
# recompute new-style fields
|
||||||
recs.recompute()
|
recs.recompute()
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue