diff options
| author | Raphael Collet <rco@odoo.com> | 2019-10-15 14:07:39 +0000 |
|---|---|---|
| committer | fw-bot <otis@odoo.com> | 2019-10-21 09:08:10 +0000 |
| commit | 883fd9e045350512c437fe8e518f08e3b880b511 (patch) | |
| tree | 954f592b9eba3303e8561735605d4f34b1dde5e6 /odoo/fields.py | |
| parent | db90ae1cd6b7417d17f0af076d9ec1987d94b509 (diff) | |
[FIX] fields: ensure Binary are never recomputed with "bin_size"
The compute methods are always expecting the real value and not the bin_size.
The solution is to always compute with `bin_size=False`, and then manually
compute the `bin_size` and set it on the cache of `bin_size=True`.
PR: #38292
Co-authored-by Sébastien Theys <seb@odoo.com>
X-original-commit: 7744886d6141ca7971d91807d0444c707e10fdf8
Diffstat (limited to 'odoo/fields.py')
| -rw-r--r-- | odoo/fields.py | 33 |
1 files changed, 29 insertions, 4 deletions
diff --git a/odoo/fields.py b/odoo/fields.py index b757beae734..4abdc9dcf1f 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -3,15 +3,13 @@ """ High-level objects for fields. """ -from collections import OrderedDict, defaultdict +from collections import defaultdict from datetime import date, datetime, time -from dateutil.relativedelta import relativedelta -from functools import partial from operator import attrgetter import itertools import logging import base64 - +import binascii import pytz try: @@ -28,6 +26,7 @@ from .tools import DEFAULT_SERVER_DATE_FORMAT as DATE_FORMAT from .tools import DEFAULT_SERVER_DATETIME_FORMAT as DATETIME_FORMAT from .tools.translate import html_translate, _ from .tools.mimetypes import guess_mimetype +from odoo.exceptions import CacheMiss DATE_LENGTH = len(date.today().strftime(DATE_FORMAT)) DATETIME_LENGTH = len(datetime.now().strftime(DATETIME_FORMAT)) @@ -1904,6 +1903,32 @@ class Binary(Field): return bytes(value) return False if value is None else value + def compute_value(self, records): + bin_size_name = 'bin_size_' + self.name + if records.env.context.get('bin_size') or records.env.context.get(bin_size_name): + # always compute without bin_size + records_no_bin_size = records.with_context(**{'bin_size': False, bin_size_name: False}) + super().compute_value(records_no_bin_size) + # manually update the bin_size cache + cache = records.env.cache + for record_no_bin_size, record in zip(records_no_bin_size, records): + try: + value = cache.get(record_no_bin_size, self) + try: + value = base64.b64decode(value) + except (TypeError, binascii.Error): + pass + try: + value = human_size(len(value)) + except (TypeError): + pass + cache_value = self.convert_to_cache(value, record) + cache.set(record, self, cache_value) + except CacheMiss: + pass + else: + super().compute_value(records) + def read(self, records): # values are stored in attachments, retrieve them assert self.attachment |
