[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:
committed by
Raphael Collet
parent
1f33ee82d0
commit
c7fe955daa
@@ -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
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user