From 9112972e155cbced84f9e1082a4b229a5b3e1fd9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Mon, 23 Sep 2019 12:40:20 +0000 Subject: [PATCH] [IMP] fields: write only once per Image field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Before this commit, flushing a model that uses the `image.mixin` would generate twice as many queries as it should. This is because `_compute_related` is not meant to be overridden. In the override of `Image` we call `super()` then post process the records by reassigning each record's relevant image field with `_image_process`. The `super()` will assign the field of the records once which will in turn trigger a `write` (and thus, will generate queries) then after the `super()` call we reassign them which will re-trigger the same `write` and the same queries. With this commit, instead of overriding `_compute_related` we extract the processing to a method that can be overridden, so that the `write` is called simply once. The result, obviously, is that queries related to the `write` are cut in half. Related PR: #36683 & #36288 Co-authored-by: Adrian Torres Co-authored-by: Sébastien Theys --- odoo/fields.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/odoo/fields.py b/odoo/fields.py index 22f5d1d56c3..7670830d770 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -628,7 +628,11 @@ class Field(MetaField('DummyField', (object,), {})): ) # assign final values to records for record, value in zip(records, values): - record[self.name] = value[self.related_field.name] + record[self.name] = self._process_related(value[self.related_field.name]) + + def _process_related(self, value): + """No transformation by default, but allows override.""" + return value def _inverse_related(self, records): """ Inverse the related field ``self`` on ``records``. """ @@ -2002,10 +2006,9 @@ class Image(Binary): value = image_process(value, size=(self.max_width, self.max_height)) return value - def _compute_related(self, records): - super(Image, self)._compute_related(records) - for record in records: - record[self.name] = self._image_process(record[self.name]) + def _process_related(self, value): + """Override to resize the related value before saving it on self.""" + return self._image_process(super()._process_related(value)) class Selection(Field):