summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--openerp/addons/base/tests/test_api.py2
-rw-r--r--openerp/fields.py48
-rw-r--r--openerp/models.py4
3 files changed, 35 insertions, 19 deletions
diff --git a/openerp/addons/base/tests/test_api.py b/openerp/addons/base/tests/test_api.py
index 6f623b3f3f4..645c5d4ad9b 100644
--- a/openerp/addons/base/tests/test_api.py
+++ b/openerp/addons/base/tests/test_api.py
@@ -339,7 +339,7 @@ class TestAPI(common.TransactionCase):
self.assertItemsEqual(partners.ids, country_id_cache)
# partners' countries are ready for prefetching
- country_ids = set(c.id for c in country_id_cache.itervalues() if c)
+ country_ids = set(cid for cids in country_id_cache.itervalues() for cid in cids)
self.assertTrue(len(country_ids) > 1)
self.assertItemsEqual(country_ids, partners._prefetch['res.country'])
diff --git a/openerp/fields.py b/openerp/fields.py
index 9bb67944254..bafd4081314 100644
--- a/openerp/fields.py
+++ b/openerp/fields.py
@@ -1571,16 +1571,24 @@ class Reference(Selection):
"Reference field %s with non-integer size %r" % (self, self.size)
def convert_to_cache(self, value, record, validate=True):
+ # cache format: (res_model, res_id) or False
+ def process(res_model, res_id):
+ record._prefetch[res_model].add(res_id)
+ return (res_model, res_id)
+
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).with_prefetch(record._prefetch) or False
+ return process(value._name, value.id) if value else False
elif isinstance(value, basestring):
res_model, res_id = value.split(',')
- return record.env[res_model].browse(int(res_id), record._prefetch)
+ return process(res_model, int(res_id))
elif not value:
return False
raise ValueError("Wrong value for %s: %r" % (self, value))
+ def convert_to_record(self, value, record):
+ return value and record.env[value[0]].browse([value[1]], record._prefetch)
+
def convert_to_read(self, value, record, use_name_get=True):
return "%s,%s" % (value._name, value.id) if value else False
@@ -1690,21 +1698,25 @@ class Many2one(_Relational):
records._cache[self] = self.convert_to_cache(value, records, validate=False)
def convert_to_cache(self, value, record, validate=True):
- if isinstance(value, (NoneType, int, long)):
- return record.env[self.comodel_name].browse(value, record._prefetch)
- if isinstance(value, BaseModel):
+ # cache format: tuple(ids)
+ def process(ids):
+ return record._prefetch[self.comodel_name].update(ids) or ids
+
+ if type(value) in IdType:
+ return process((value,))
+ elif isinstance(value, BaseModel):
if not validate or (value._name == self.comodel_name and len(value) <= 1):
- return value.with_env(record.env).with_prefetch(record._prefetch)
+ return process(value._ids)
raise ValueError("Wrong value for %s: %r" % (self, value))
elif isinstance(value, tuple):
- return record.env[self.comodel_name].browse(value[0], record._prefetch)
+ return process((value[0],))
elif isinstance(value, dict):
- return record.env[self.comodel_name].new(value)
+ return process(record.env[self.comodel_name].new(value)._ids)
else:
- return record.env[self.comodel_name]
+ return ()
def convert_to_record(self, value, record):
- return value.with_prefetch(record._prefetch)
+ return record.env[self.comodel_name]._browse(value, record.env, record._prefetch)
def convert_to_read(self, value, record, use_name_get=True):
if use_name_get and value:
@@ -1760,9 +1772,13 @@ class _RelationalMulti(_Relational):
record._cache[self] = value
def convert_to_cache(self, value, record, validate=True):
+ # cache format: tuple(ids)
+ def process(ids):
+ return record._prefetch[self.comodel_name].update(ids) or ids
+
if isinstance(value, BaseModel):
if not validate or (value._name == self.comodel_name):
- return value.with_env(record.env).with_prefetch(record._prefetch)
+ return process(value._ids)
elif isinstance(value, list):
# value is a list of record ids or commands
comodel = record.env[self.comodel_name]
@@ -1791,14 +1807,14 @@ class _RelationalMulti(_Relational):
ids.add(comodel.new(command).id)
else:
ids.add(command)
- # return result as a recordset
- return comodel.browse(list(ids), record._prefetch)
+ # return result as a tuple
+ return process(tuple(ids))
elif not value:
- return record.env[self.comodel_name]
+ return ()
raise ValueError("Wrong value for %s: %s" % (self, value))
def convert_to_record(self, value, record):
- return value.with_prefetch(record._prefetch)
+ return record.env[self.comodel_name]._browse(value, record.env, record._prefetch)
def convert_to_read(self, value, record, use_name_get=True):
return value.ids
@@ -2030,5 +2046,5 @@ class Id(Field):
# imported here to avoid dependency cycle issues
from openerp import SUPERUSER_ID
from .exceptions import AccessError, MissingError
-from .models import check_pg_name, BaseModel
+from .models import check_pg_name, BaseModel, IdType
from .osv import fields
diff --git a/openerp/models.py b/openerp/models.py
index 3b3c093c0a7..35356269004 100644
--- a/openerp/models.py
+++ b/openerp/models.py
@@ -269,7 +269,7 @@ class NewId(object):
def __nonzero__(self):
return False
-IdType = (int, long, basestring, NewId)
+IdType = (int, long, str, unicode, NewId)
# maximum number of prefetched records
@@ -6422,7 +6422,7 @@ PGERROR_TO_OE = defaultdict(
'23505': convert_pgerror_23505,
})
-def _normalize_ids(arg, atoms={int, long, str, unicode, NewId}):
+def _normalize_ids(arg, atoms=set(IdType)):
""" Normalizes the ids argument for ``browse`` (v7 and v8) to a tuple.
Various implementations were tested on the corpus of all browse() calls