summaryrefslogtreecommitdiff
path: root/odoo/fields.py
diff options
context:
space:
mode:
authorChristophe Simonis <chs@odoo.com>2018-11-29 20:06:16 +0100
committerChristophe Simonis <chs@odoo.com>2018-11-29 20:06:16 +0100
commitce4cc24621bf6430d7d3a2d469b375b59120c200 (patch)
tree3837b5fe41ff88b24136ab53c871bc01f965cab1 /odoo/fields.py
parent4d7aa97da38e497fef31a06543bfa5d2c8785708 (diff)
parent82a1e1dcc33d7c123e50d3e1aacb5e127f57c521 (diff)
[MERGE] forward port branch 12.0 up to 82a1e1dcc33
Diffstat (limited to 'odoo/fields.py')
-rw-r--r--odoo/fields.py39
1 files changed, 27 insertions, 12 deletions
diff --git a/odoo/fields.py b/odoo/fields.py
index 8da18806f96..a69edde187d 100644
--- a/odoo/fields.py
+++ b/odoo/fields.py
@@ -2164,6 +2164,26 @@ class Many2one(_Relational):
return super(Many2one, self).convert_to_onchange(value, record, names)
+class _RelationalMultiUpdate(object):
+ """ A getter to update the value of an x2many field, without reading its
+ value until necessary.
+ """
+ __slots__ = ['record', 'field', 'value']
+
+ def __init__(self, record, field, value):
+ self.record = record
+ self.field = field
+ self.value = value
+
+ def __call__(self):
+ # determine the current field's value, and update it in cache only
+ record, field, value = self.record, self.field, self.value
+ cache = record.env.cache
+ cache.remove(record, field)
+ val = field.convert_to_cache(record[field.name] | value, record, validate=False)
+ cache.set(record, field, val)
+ return val
+
class _RelationalMulti(_Relational):
""" Abstract class for relational fields *2many. """
@@ -2175,7 +2195,12 @@ class _RelationalMulti(_Relational):
""" Update the cached value of ``self`` for ``records`` with ``value``. """
cache = records.env.cache
for record in records:
- if cache.contains(record, self):
+ special = cache.get_special(record, self)
+ if isinstance(special, _RelationalMultiUpdate):
+ # include 'value' in the existing _RelationalMultiUpdate; this
+ # avoids reading the field's value (which may be large)
+ special.value |= value
+ elif cache.contains(record, self):
try:
val = self.convert_to_cache(record[self.name] | value, record, validate=False)
cache.set(record, self, val)
@@ -2183,17 +2208,7 @@ class _RelationalMulti(_Relational):
# delay the failure until the field is necessary
cache.set_failed(record, [self], exc)
else:
- cache.set_special(record, self, self._update_getter(record, value))
-
- def _update_getter(self, record, value):
- def getter():
- # determine the current field's value, and update it in cache only
- cache = record.env.cache
- cache.remove(record, self)
- val = self.convert_to_cache(record[self.name] | value, record, validate=False)
- cache.set(record, self, val)
- return val
- return getter
+ cache.set_special(record, self, _RelationalMultiUpdate(record, self, value))
def convert_to_cache(self, value, record, validate=True):
# cache format: tuple(ids)