From 5676d8121d97ba02596e5e3d78971d587fa9d3e7 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Fri, 6 May 2016 10:47:29 +0200 Subject: [PATCH] [FIX] fields: invalidate x2many fields with a domain Invalidate the cache of a x2many field when any of the fields appearing in its domain is modified. Use the invalidation triggers mechanism for that purpose. --- openerp/addons/test_new_api/models.py | 3 +++ openerp/addons/test_new_api/tests/test_new_fields.py | 8 ++++++++ openerp/fields.py | 11 ++++++++++- 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/openerp/addons/test_new_api/models.py b/openerp/addons/test_new_api/models.py index 50993d24277..2d6d17db541 100644 --- a/openerp/addons/test_new_api/models.py +++ b/openerp/addons/test_new_api/models.py @@ -143,6 +143,8 @@ class Discussion(models.Model): participants = fields.Many2many('res.users') messages = fields.One2many('test_new_api.message', 'discussion') message_changes = fields.Integer(string='Message changes') + important_messages = fields.One2many('test_new_api.message', 'discussion', + domain=[('important', '=', True)]) @api.onchange('moderator') def _onchange_moderator(self): @@ -167,6 +169,7 @@ class Message(models.Model): author_partner = fields.Many2one( 'res.partner', compute='_compute_author_partner', search='_search_author_partner') + important = fields.Boolean() @api.one @api.constrains('author', 'discussion') diff --git a/openerp/addons/test_new_api/tests/test_new_fields.py b/openerp/addons/test_new_api/tests/test_new_fields.py index 6ee9a4a664e..16cb198c005 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -448,6 +448,14 @@ class TestNewFields(common.TransactionCase): [('author_partner.name', '=', 'Demo User')]) self.assertEqual(messages, self.env.ref('test_new_api.message_0_1')) + def test_60_x2many_domain(self): + """ test the cache consistency of a x2many field with a domain """ + discussion = self.env.ref('test_new_api.discussion_0') + message = discussion.messages[0] + self.assertNotIn(message, discussion.important_messages) + + message.important = True + self.assertIn(message, discussion.important_messages) class TestMagicFields(common.TransactionCase): diff --git a/openerp/fields.py b/openerp/fields.py index 94e15f1bac9..e44caaf1f31 100644 --- a/openerp/fields.py +++ b/openerp/fields.py @@ -971,7 +971,7 @@ class Field(object): # invalidate the fields that depend on self, and prepare recomputation spec = [(self, records._ids)] for field, path in self._triggers: - if path and field.store: + if path and field.compute and field.store: # don't move this line to function top, see log env = records.env(user=SUPERUSER_ID, context={'active_test': False}) target = env[field.model_name].search([(path, 'in', records.ids)]) @@ -1723,6 +1723,15 @@ class _RelationalMulti(_Relational): for record in records: record[self.name] = record[self.name].filtered(accessible) + def setup_triggers(self, env): + super(_RelationalMulti, self).setup_triggers(env) + # also invalidate self when fields appearing in the domain are modified + if isinstance(self.domain, list): + comodel = env[self.comodel_name] + for arg in self.domain: + if isinstance(arg, (tuple, list)) and isinstance(arg[0], basestring): + self._setup_dependency([self.name], comodel, arg[0].split('.')) + class One2many(_RelationalMulti): """ One2many field; the value of such a field is the recordset of all the