diff --git a/odoo/addons/test_new_api/models/test_new_api.py b/odoo/addons/test_new_api/models/test_new_api.py index 47df3602baa..27af01e335b 100644 --- a/odoo/addons/test_new_api/models/test_new_api.py +++ b/odoo/addons/test_new_api/models/test_new_api.py @@ -1127,3 +1127,23 @@ class ShareCacheComputeLine(models.Model): parent_id = fields.Many2one('test_new_api.model_shared_cache_compute_parent') amount = fields.Integer() user_id = fields.Many2one('res.users', default= lambda self: self.env.user) # Note: There is an ir.rule about this. + + +class ComputeContainer(models.Model): + _name = _description = 'test_new_api.compute.container' + + name = fields.Char() + member_ids = fields.One2many('test_new_api.compute.member', 'container_id') + + +class ComputeMember(models.Model): + _name = _description = 'test_new_api.compute.member' + + name = fields.Char() + container_id = fields.Many2one('test_new_api.compute.container', compute='_compute_container', store=True) + + @api.depends('name') + def _compute_container(self): + container = self.env['test_new_api.compute.container'] + for member in self: + member.container_id = container.search([('name', '=', member.name)], limit=1) diff --git a/odoo/addons/test_new_api/security/ir.model.access.csv b/odoo/addons/test_new_api/security/ir.model.access.csv index 466b014f213..71a309d5d1a 100644 --- a/odoo/addons/test_new_api/security/ir.model.access.csv +++ b/odoo/addons/test_new_api/security/ir.model.access.csv @@ -64,3 +64,5 @@ access_test_new_api_move,access_test_new_api_move,model_test_new_api_move,,1,1,1 access_test_new_api_move_line,access_test_new_api_move_line,model_test_new_api_move_line,,1,1,1,1 access_test_new_api_model_shared_cache_compute_parent,access_test_new_api.model_shared_cache_compute_parent,model_test_new_api_model_shared_cache_compute_parent,,1,1,1,1 access_test_new_api_model_shared_cache_compute_line,access_test_new_api.model_shared_cache_compute_line,model_test_new_api_model_shared_cache_compute_line,,1,1,1,1 +access_test_new_api_compute_container,access_test_new_api_compute_container,model_test_new_api_compute_container,,1,1,1,1 +access_test_new_api_compute_member,access_test_new_api_compute_member,model_test_new_api_compute_member,,1,1,1,1 diff --git a/odoo/addons/test_new_api/tests/test_one2many.py b/odoo/addons/test_new_api/tests/test_one2many.py index a2be1d9709e..f9d2be27190 100644 --- a/odoo/addons/test_new_api/tests/test_one2many.py +++ b/odoo/addons/test_new_api/tests/test_one2many.py @@ -247,3 +247,11 @@ class One2manyCase(TransactionCase): # delete parent, and check that recomputation ends parent.unlink() parent.flush() + + def test_compute_stored_many2one_one2many(self): + container = self.env['test_new_api.compute.container'].create({'name': 'Foo'}) + self.assertFalse(container.member_ids) + member = self.env['test_new_api.compute.member'].create({'name': 'Foo'}) + # at this point, member.container_id must be computed for member to + # appear in container.member_ids + self.assertEqual(container.member_ids, member) diff --git a/odoo/fields.py b/odoo/fields.py index f840585414f..7656b279004 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -3055,6 +3055,15 @@ class One2many(_RelationalMulti): domain = domain + [(inverse_field.model_field, '=', records._name)] return domain + def __get__(self, records, owner): + if records is not None and self.inverse_name is not None: + # force the computation of the inverse field to ensure that the + # cache value of self is consistent + inverse_field = records.pool[self.comodel_name]._fields[self.inverse_name] + if inverse_field.compute: + records.env[self.comodel_name].recompute([self.inverse_name]) + return super().__get__(records, owner) + def read(self, records): # retrieve the lines in the comodel context = {'active_test': False}