From c7fe955daa08d2ba264f6e3f6b4b919cc7713aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=A9bastien=20Theys?= Date: Tue, 9 Apr 2019 06:47:52 +0000 Subject: [PATCH] [FIX] fields: prevent caching wrong value when it's altered by write Before this commit, the field assignment would cache the value it received, even if that value was altered during `write`. This can happen if `write` is overridden (for example to resize images), or it could also happen if a database procedure is altering the value. To fix this issue, we do not cache the value that was assigned. This implies that additional queries may be necessary to retrieve the value, but those were already necessary most of the time, so it does not have a significant impact on performances. --- odoo/addons/test_new_api/models.py | 7 +++++++ odoo/addons/test_new_api/tests/test_new_fields.py | 4 ++++ odoo/fields.py | 4 +++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/odoo/addons/test_new_api/models.py b/odoo/addons/test_new_api/models.py index 4b27de7d207..e6ad747097d 100644 --- a/odoo/addons/test_new_api/models.py +++ b/odoo/addons/test_new_api/models.py @@ -128,6 +128,7 @@ class Message(models.Model): search='_search_author_partner') important = fields.Boolean() label = fields.Char(translate=True) + priority = fields.Integer() @api.one @api.constrains('author', 'discussion') @@ -186,6 +187,12 @@ class Message(models.Model): def _search_author_partner(self, operator, value): return [('author.partner_id', operator, value)] + @api.multi + def write(self, vals): + if 'priority' in vals: + vals['priority'] = 5 + return super().write(vals) + class EmailMessage(models.Model): _name = 'test_new_api.emailmessage' diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index f49aea62b1f..328a0f69ab8 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -52,6 +52,10 @@ class TestFields(common.TransactionCase): with self.assertRaises(ValueError): records.body = 'Faulty' + # field assigmenent does not cache the wrong value when write overridden + record.priority = 4 + self.assertEqual(record.priority, 5) + def test_10_computed(self): """ check definition of computed fields """ # by default function fields are not stored and readonly diff --git a/odoo/fields.py b/odoo/fields.py index 16a13bedbe4..8d977e6cde3 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -1029,10 +1029,12 @@ class Field(MetaField('DummyField', (object,), {})): spec += self.modified_draft(record) env.cache.invalidate(spec) - else: + elif (self.store or self.inverse or self.inherited): # Write to database write_value = self.convert_to_write(self.convert_to_record(value, record), record) record.write({self.name: write_value}) + + else: # Update the cache unless value contains a new record if not (self.relational and not all(value)): record.env.cache.set(record, self, value)