diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 91cfa912c63..ad831bf5b3b 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -278,6 +278,13 @@ class TestFields(common.TransactionCase): self.assertEqual(ewan.parent, cath) self.assertEqual(ewan.name, "Erwan") + # write on non-stored inverse field on severals records + foo1 = Category.create({'name': 'Foo'}) + foo2 = Category.create({'name': 'Foo'}) + (foo1 + foo2).write({'display_name': 'Bar'}) + self.assertEqual(foo1.name, 'Bar') + self.assertEqual(foo2.name, 'Bar') + # create/write on 'foo' should only invoke the compute method log = [] model = self.env['test_new_api.compute.inverse'].with_context(log=log) diff --git a/odoo/models.py b/odoo/models.py index 89055976394..f7ca90c5002 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3035,14 +3035,23 @@ class BaseModel(MetaModel('DummyModel', (object,), {'_register': False})): self.env[model_name].browse(parent_ids).write(parent_vals) if inverse_vals: - # put the values of inverse fields in cache, and inverse them self.modified(set(inverse_vals) - set(store_vals)) - for record in self: - record._cache.update(record._convert_to_cache(inverse_vals, update=True)) # in case several fields use the same inverse method, call it once for _inv, fields in groupby(inverse_fields, attrgetter('inverse')): - fields[0].determine_inverse(self) + # If a field is not stored, its inverse method will probably + # write on its dependencies, which will invalidate the field + # on all records. We therefore inverse the field one record + # at a time. + batches = [self] if all(f.store for f in fields) else list(self) + # put the values of fields in cache, and inverse them + inv_vals = {f.name: inverse_vals[f.name] for f in fields} + for records in batches: + for record in records: + record._cache.update( + record._convert_to_cache(inv_vals, update=True) + ) + fields[0].determine_inverse(records) self.modified(set(inverse_vals) - set(store_vals))