[FIX] models: do not prefetch fields to recompute, and recompute once only
The method _prefetch_field() was accidentally prefetching fields to recompute; which was skipping the actual recomputation, since a value was put in cache. But sometimes the field's value was fixed by an extra recomputation of the field. Here we remove the extra recomputation and fix the cache corruption.
This commit is contained in:
parent
cfa04b1d3d
commit
044ed06fec
|
@ -837,11 +837,10 @@ class Environment(object):
|
|||
|
||||
def remove_todo(self, field, records):
|
||||
""" Mark `field` as recomputed on `records`. """
|
||||
recs_list = self.all.todo.get(field, [])
|
||||
if records in recs_list:
|
||||
recs_list.remove(records)
|
||||
if not recs_list:
|
||||
del self.all.todo[field]
|
||||
recs_list = [recs - records for recs in self.all.todo.pop(field, [])]
|
||||
recs_list = filter(None, recs_list)
|
||||
if recs_list:
|
||||
self.all.todo[field] = recs_list
|
||||
|
||||
def has_todo(self):
|
||||
""" Return whether some fields must be recomputed. """
|
||||
|
|
|
@ -3127,25 +3127,27 @@ class BaseModel(object):
|
|||
if len(records) > PREFETCH_MAX:
|
||||
records = records[:PREFETCH_MAX] | self
|
||||
|
||||
# by default, simply fetch field
|
||||
fnames = {field.name}
|
||||
|
||||
if self.env.in_draft:
|
||||
# we may be doing an onchange, do not prefetch other fields
|
||||
pass
|
||||
elif self.env.field_todo(field):
|
||||
# field must be recomputed, do not prefetch records to recompute
|
||||
records -= self.env.field_todo(field)
|
||||
elif not self._context.get('prefetch_fields', True):
|
||||
# do not prefetch other fields
|
||||
pass
|
||||
elif self._columns[field.name]._prefetch:
|
||||
# here we can optimize: prefetch all classic and many2one fields
|
||||
fnames = set(fname
|
||||
# determine which fields can be prefetched
|
||||
if not self.env.in_draft and \
|
||||
self._context.get('prefetch_fields', True) and \
|
||||
self._columns[field.name]._prefetch:
|
||||
# prefetch all classic and many2one fields that the user can access
|
||||
fnames = {fname
|
||||
for fname, fcolumn in self._columns.iteritems()
|
||||
if fcolumn._prefetch
|
||||
if not fcolumn.groups or self.user_has_groups(fcolumn.groups)
|
||||
)
|
||||
}
|
||||
else:
|
||||
fnames = {field.name}
|
||||
|
||||
# important: never prefetch fields to recompute!
|
||||
get_recs_todo = self.env.field_todo
|
||||
for fname in list(fnames):
|
||||
if get_recs_todo(self._fields[fname]):
|
||||
if fname == field.name:
|
||||
records -= get_recs_todo(field)
|
||||
else:
|
||||
fnames.discard(fname)
|
||||
|
||||
# fetch records with read()
|
||||
assert self in records and field.name in fnames
|
||||
|
|
Loading…
Reference in New Issue