summaryrefslogtreecommitdiff
path: root/openerp/models.py
diff options
context:
space:
mode:
authorOlivier Dony <odo@openerp.com>2014-07-23 12:30:24 +0200
committerOlivier Dony <odo@openerp.com>2014-07-23 12:30:24 +0200
commit8974e928fa9f9b54ef3fbaf685aedbcccd2c755d (patch)
treed6836ed019b0b3d8bfc40a22466a3e0c267aa282 /openerp/models.py
parent42f3575bb3fdc6c0b2a5c43685d7bd99d771f2fd (diff)
[FIX] fields: do not revalidate field values unless they are being modified
In the previous implementation of the new API fields, both fields.Selection and fields.Reference were performing early validation of their `value` as soon as it entered the cache, either by being read, written, or computed. This is a source of trouble and performance problems, and is unnecessary, as we should consider that the database always contains valid values. If that is not the case it means it was modified externally and is an exception that should be handled externally as well. Revalidating selection/reference values can be expensive when the domain of values is dynamic and requires extra database queries, with extra access rights control, etc. This patch adds a `validate` parameter to `convert_to_cache`, allowing to turn off the re-validation on demand. The ORM will turn off validation whenever the value being converted is supposed to be already validated, such as when reading it from the database. The parameter is currently ignored by all other fields, and defaults to True so validation is performed in all other caes.
Diffstat (limited to 'openerp/models.py')
-rw-r--r--openerp/models.py13
1 files changed, 6 insertions, 7 deletions
diff --git a/openerp/models.py b/openerp/models.py
index ecc8c7263fa..fffdd93a53c 100644
--- a/openerp/models.py
+++ b/openerp/models.py
@@ -3136,7 +3136,7 @@ class BaseModel(object):
if field not in self._cache:
for values in result:
record = self.browse(values.pop('id'))
- record._cache.update(record._convert_to_cache(values))
+ record._cache.update(record._convert_to_cache(values, validate=False))
if field not in self._cache:
e = AccessError("No value found for %s.%s" % (self, field.name))
self._cache[field] = FailedValue(e)
@@ -3215,7 +3215,7 @@ class BaseModel(object):
# store result in cache for POST fields
for vals in result:
record = self.browse(vals['id'])
- record._cache.update(record._convert_to_cache(vals))
+ record._cache.update(record._convert_to_cache(vals, validate=False))
# determine the fields that must be processed now
fields_post = [f for f in field_names if not self._columns[f]._classic_write]
@@ -3256,7 +3256,7 @@ class BaseModel(object):
# store result in cache
for vals in result:
record = self.browse(vals.pop('id'))
- record._cache.update(record._convert_to_cache(vals))
+ record._cache.update(record._convert_to_cache(vals, validate=False))
# store failed values in cache for the records that could not be read
fetched = self.browse(ids)
@@ -3596,7 +3596,6 @@ class BaseModel(object):
if not self:
return True
- cr, uid, context = self.env.args
self._check_concurrency(self._ids)
self.check_access_rights('write')
@@ -5098,11 +5097,11 @@ class BaseModel(object):
context = dict(args[0] if args else self._context, **kwargs)
return self.with_env(self.env(context=context))
- def _convert_to_cache(self, values):
+ def _convert_to_cache(self, values, validate=True):
""" Convert the `values` dictionary into cached values. """
fields = self._fields
return {
- name: fields[name].convert_to_cache(value, self.env)
+ name: fields[name].convert_to_cache(value, self.env, validate=validate)
for name, value in values.iteritems()
if name in fields
}
@@ -5555,7 +5554,7 @@ class BaseModel(object):
return
if 'value' in method_res:
method_res['value'].pop('id', None)
- self.update(self._convert_to_cache(method_res['value']))
+ self.update(self._convert_to_cache(method_res['value'], validate=False))
if 'domain' in method_res:
result.setdefault('domain', {}).update(method_res['domain'])
if 'warning' in method_res: