[IMP] fields: update inverse fields lazily for performance
When a relational field is assigned in an onchange, its inverse field is updated in cache. Reading the current value of the inverse field may be costly, for instance in the case of a one2many field with thousands of records as a value. Instead, put in cache a SpecialValue that reads and updates the field; it will be triggered only when it is accessed.
This commit is contained in:
parent
4a10295823
commit
e7b8e107f1
|
@ -1386,13 +1386,32 @@ class Many2one(_Relational):
|
|||
record[self.name] = record.env[self.comodel_name].new()
|
||||
|
||||
|
||||
class UnionUpdate(SpecialValue):
|
||||
""" Placeholder for a value update; when this value is taken from the cache,
|
||||
it returns ``record[field.name] | value`` and stores it in the cache.
|
||||
"""
|
||||
def __init__(self, field, record, value):
|
||||
self.args = (field, record, value)
|
||||
|
||||
def get(self):
|
||||
field, record, value = self.args
|
||||
# in order to read the current field's value, remove self from cache
|
||||
del record._cache[field]
|
||||
# read the current field's value, and update it in cache only
|
||||
record._cache[field] = new_value = record[field.name] | value
|
||||
return new_value
|
||||
|
||||
|
||||
class _RelationalMulti(_Relational):
|
||||
""" Abstract class for relational fields *2many. """
|
||||
|
||||
def _update(self, records, value):
|
||||
""" Update the cached value of `self` for `records` with `value`. """
|
||||
for record in records:
|
||||
record._cache[self] = record[self.name] | value
|
||||
if self in record._cache:
|
||||
record._cache[self] = record[self.name] | value
|
||||
else:
|
||||
record._cache[self] = UnionUpdate(self, record, value)
|
||||
|
||||
def convert_to_cache(self, value, record, validate=True):
|
||||
if isinstance(value, BaseModel):
|
||||
|
|
Loading…
Reference in New Issue