[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.
This commit is contained in:
Sébastien Theys
2019-04-11 14:55:36 +00:00
committed by Raphael Collet
parent 1f33ee82d0
commit c7fe955daa
3 changed files with 14 additions and 1 deletions
+7
View File
@@ -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'
@@ -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
+3 -1
View File
@@ -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)