diff options
| author | Christophe Simonis <chs@odoo.com> | 2018-11-29 18:38:55 +0100 |
|---|---|---|
| committer | Christophe Simonis <chs@odoo.com> | 2018-11-29 18:38:55 +0100 |
| commit | f5c3dafb045f4eb5e832c45596dd59396667ea09 (patch) | |
| tree | 8265091d53c54dfa47e5a67f00e98cfda404ade2 /odoo/fields.py | |
| parent | 5644ab53ab6f370a2fb48242e22702655afd6655 (diff) | |
| parent | c0eef4271110ebcab07811328a7b3f4309fb4d06 (diff) | |
[MERGE] forward port branch saas-11.3 up to c0eef427111
Diffstat (limited to 'odoo/fields.py')
| -rw-r--r-- | odoo/fields.py | 39 |
1 files changed, 27 insertions, 12 deletions
diff --git a/odoo/fields.py b/odoo/fields.py index 00923886d0a..ce49ddc5e93 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -2166,6 +2166,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. """ @@ -2177,7 +2197,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) @@ -2185,17 +2210,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) |
