Permalink
Browse files

[FIX] base: optimize the reading of many2one property fields

  • Loading branch information...
rco-odoo committed Sep 14, 2018
1 parent d39d583 commit 70ed882088401c093e6a1180746b5637fe96da32
@@ -159,11 +159,31 @@ def get_multi(self, name, model, ids):
# note: order by 'company_id asc' will return non-null values first
props = self.search(domain, order='company_id asc')
result = {}
for prop in props:
# for a given res_id, take the first property only
id = refs.pop(prop.res_id, None)
if id is not None:
result[id] = prop.get_by_record()
field = self.env[model]._fields[name]
if field.type == 'many2one':
# optimization for many2one fields
Comodel = self.env[field.comodel_name]
co_ids = set()
for prop in props:
# for a given res_id, take the first property only
id = refs.pop(prop.res_id, None)
if id is not None:
val = prop.value_reference
if val:
val = int(val.split(',')[1])
co_ids.add(val)
result[id] = val
# check for existence in batch, and update result accordingly
existing = {rec.id: rec for rec in Comodel.browse(co_ids).exists()}
result = {id: existing.get(val, Comodel) for id, val in result.items()}
else:
for prop in props:
# for a given res_id, take the first property only
id = refs.pop(prop.res_id, None)
if id is not None:
result[id] = prop.get_by_record()
# set the default value to the ids that are not in result
default_value = result.pop(False, False)
@@ -349,6 +349,7 @@ class CompanyDependent(models.Model):
_name = 'test_new_api.company'
foo = fields.Char(company_dependent=True)
tag_id = fields.Many2one('test_new_api.multi.tag', company_dependent=True)
class CompanyDependentAttribute(models.Model):
_name = 'test_new_api.company.attr'
@@ -564,31 +564,52 @@ def test_27_company_dependent(self):
company0 = self.env.ref('base.main_company')
company1 = self.env['res.company'].create({'name': 'A', 'parent_id': company0.id})
company2 = self.env['res.company'].create({'name': 'B', 'parent_id': company1.id})
# create one user per company
user0 = self.env['res.users'].create({'name': 'Foo', 'login': 'foo',
'company_id': company0.id, 'company_ids': []})
user1 = self.env['res.users'].create({'name': 'Bar', 'login': 'bar',
'company_id': company1.id, 'company_ids': []})
user2 = self.env['res.users'].create({'name': 'Baz', 'login': 'baz',
'company_id': company2.id, 'company_ids': []})
# create a default value for the company-dependent field
field = self.env['ir.model.fields'].search([('model', '=', 'test_new_api.company'),
('name', '=', 'foo')])
self.env['ir.property'].create({'name': 'foo', 'fields_id': field.id,
# create values for many2one field
tag0 = self.env['test_new_api.multi.tag'].create({'name': 'Qux'})
tag1 = self.env['test_new_api.multi.tag'].create({'name': 'Quux'})
tag2 = self.env['test_new_api.multi.tag'].create({'name': 'Quuz'})
# create default values for the company-dependent fields
field_foo = self.env['ir.model.fields']._get('test_new_api.company', 'foo')
self.env['ir.property'].create({'name': 'foo', 'fields_id': field_foo.id,
'value': 'default', 'type': 'char'})
field_tag_id = self.env['ir.model.fields']._get('test_new_api.company', 'tag_id')
self.env['ir.property'].create({'name': 'foo', 'fields_id': field_tag_id.id,
'value': tag0, 'type': 'many2one'})
# create/modify a record, and check the value for each user
record = self.env['test_new_api.company'].create({'foo': 'main'})
record = self.env['test_new_api.company'].create({'foo': 'main', 'tag_id': tag1})
record.invalidate_cache()
self.assertEqual(record.sudo(user0).foo, 'main')
self.assertEqual(record.sudo(user1).foo, 'default')
self.assertEqual(record.sudo(user2).foo, 'default')
self.assertEqual(record.sudo(user0).tag_id, tag1)
self.assertEqual(record.sudo(user1).tag_id, tag0)
self.assertEqual(record.sudo(user2).tag_id, tag0)
record.sudo(user1).foo = 'alpha'
record.sudo(user1).write({'foo': 'alpha', 'tag_id': tag2.id})
record.invalidate_cache()
self.assertEqual(record.sudo(user0).foo, 'main')
self.assertEqual(record.sudo(user1).foo, 'alpha')
self.assertEqual(record.sudo(user2).foo, 'default')
self.assertEqual(record.sudo(user0).tag_id, tag1)
self.assertEqual(record.sudo(user1).tag_id, tag2)
self.assertEqual(record.sudo(user2).tag_id, tag0)
# unlink value of a many2one (tag2), and check again
tag2.unlink()
self.assertEqual(record.sudo(user0).tag_id, tag1)
self.assertEqual(record.sudo(user1).tag_id, tag0.browse())
self.assertEqual(record.sudo(user2).tag_id, tag0)
# create company record and attribute
company_record = self.env['test_new_api.company'].create({'foo': 'ABC'})

0 comments on commit 70ed882

Please sign in to comment.