diff --git a/openerp/fields.py b/openerp/fields.py index 9c9e6cdf7a1..8f3d9cd10fc 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -765,7 +765,8 @@ class Field(object): def convert_to_cache(self, value, record, validate=True): """ Convert ``value`` to the cache format; ``value`` may come from an assignment, or have the format of methods :meth:`BaseModel.read` or - :meth:`BaseModel.write`. + :meth:`BaseModel.write`. If the value represents a recordset, it should + be added for prefetching on ``record``. :param bool validate: when True, field-specific validation of ``value`` will be performed @@ -1574,10 +1575,10 @@ class Reference(Selection): def convert_to_cache(self, value, record, validate=True): if isinstance(value, BaseModel): if not validate or (value._name in self.get_values(record.env) and len(value) <= 1): - return value.with_env(record.env) or False + return value.with_env(record.env).with_prefetch(record._prefetch) or False elif isinstance(value, basestring): res_model, res_id = value.split(',') - return record.env[res_model].browse(int(res_id)) + return record.env[res_model].browse(int(res_id), record._prefetch) elif not value: return False raise ValueError("Wrong value for %s: %r" % (self, value)) @@ -1689,13 +1690,13 @@ class Many2one(_Relational): def convert_to_cache(self, value, record, validate=True): if isinstance(value, (NoneType, int, long)): - return record.env[self.comodel_name].browse(value) + return record.env[self.comodel_name].browse(value, record._prefetch) if isinstance(value, BaseModel): if not validate or (value._name == self.comodel_name and len(value) <= 1): - return value.with_env(record.env) + return value.with_env(record.env).with_prefetch(record._prefetch) raise ValueError("Wrong value for %s: %r" % (self, value)) elif isinstance(value, tuple): - return record.env[self.comodel_name].browse(value[0]) + return record.env[self.comodel_name].browse(value[0], record._prefetch) elif isinstance(value, dict): return record.env[self.comodel_name].new(value) else: @@ -1758,7 +1759,7 @@ class _RelationalMulti(_Relational): def convert_to_cache(self, value, record, validate=True): if isinstance(value, BaseModel): if not validate or (value._name == self.comodel_name): - return value.with_env(record.env) + return value.with_env(record.env).with_prefetch(record._prefetch) elif isinstance(value, list): # value is a list of record ids or commands comodel = record.env[self.comodel_name] @@ -1788,7 +1789,7 @@ class _RelationalMulti(_Relational): else: ids.add(command) # return result as a recordset - return comodel.browse(list(ids)) + return comodel.browse(list(ids), record._prefetch) elif not value: return record.env[self.comodel_name] raise ValueError("Wrong value for %s: %s" % (self, value)) diff --git a/openerp/models.py b/openerp/models.py index 8c9c183903e..721cce01edc 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -3380,7 +3380,8 @@ class BaseModel(object): else: _logger.warning("%s.read() with unknown field '%s'", self._name, name) - # fetch stored fields from the database to the cache + # fetch stored fields from the database to the cache; this should feed + # the prefetching of secondary records self._read_from_database(stored, inherited) # retrieve results from records; this takes values from the cache and @@ -3449,6 +3450,7 @@ class BaseModel(object): # fetch records with read() assert self in records and field in fs + records = records.with_prefetch(self._prefetch) result = [] try: result = records.read([f.name for f in fs], load='_classic_write') @@ -3459,7 +3461,7 @@ class BaseModel(object): # check the cache, and update it if necessary if field not in self._cache: for values in result: - record = self.browse(values.pop('id')) + record = self.browse(values.pop('id'), self._prefetch) record._cache.update(record._convert_to_cache(values, validate=False)) if not self._cache.contains(field): e = AccessError("No value found for %s.%s" % (self, field.name)) @@ -3545,7 +3547,7 @@ class BaseModel(object): # store result in cache for POST fields for vals in result: - record = self.browse(vals['id']) + record = self.browse(vals['id'], self._prefetch) record._cache.update(record._convert_to_cache(vals, validate=False)) # determine the fields that must be processed now; @@ -3587,7 +3589,7 @@ class BaseModel(object): # store result in cache for vals in result: - record = self.browse(vals.pop('id')) + record = self.browse(vals.pop('id'), self._prefetch) record._cache.update(record._convert_to_cache(vals, validate=False)) # store failed values in cache for the records that could not be read @@ -5656,7 +5658,7 @@ class BaseModel(object): :param validate: whether values must be checked """ fields = self._fields - target = self if update else self.browse() + target = self if update else self.browse([], self._prefetch) return { name: fields[name].convert_to_cache(value, target, validate=validate) for name, value in values.iteritems()