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 fe118ba44ca..6ac223bd458 100644 --- a/openerp/addons/test_new_api/tests/test_new_fields.py +++ b/openerp/addons/test_new_api/tests/test_new_fields.py @@ -528,6 +528,30 @@ class TestNewFields(common.TransactionCase): self.assertFalse(discussion.very_important_messages) self.assertFalse(message.exists()) + def test_70_x2many_write(self): + discussion = self.env.ref('test_new_api.discussion_0') + Message = self.env['test_new_api.message'] + # There must be 3 messages, 0 important + self.assertEqual(len(discussion.messages), 3) + self.assertEqual(len(discussion.important_messages), 0) + self.assertEqual(len(discussion.very_important_messages), 0) + discussion.important_messages = [(0, 0, { + 'body': 'What is the answer?', + 'important': True, + })] + # There must be 4 messages, 1 important + self.assertEqual(len(discussion.messages), 4) + self.assertEqual(len(discussion.important_messages), 1) + self.assertEqual(len(discussion.very_important_messages), 1) + discussion.very_important_messages |= Message.new({ + 'body': '42', + 'important': True, + }) + # There must be 5 messages, 2 important + self.assertEqual(len(discussion.messages), 5) + self.assertEqual(len(discussion.important_messages), 2) + self.assertEqual(len(discussion.very_important_messages), 2) + class TestMagicFields(common.TransactionCase): diff --git a/openerp/osv/fields.py b/openerp/osv/fields.py index b451da449e6..99a51c4e79b 100644 --- a/openerp/osv/fields.py +++ b/openerp/osv/fields.py @@ -861,8 +861,13 @@ class one2many(_column): # Must use write() to recompute parent_store structure if needed obj.write(cr, user, act[2], {self._fields_id:id}, context=context or {}) ids2 = act[2] or [0] - cr.execute('select id from '+_table+' where '+self._fields_id+'=%s and id <> ALL (%s)', (id,ids2)) - ids3 = map(lambda x:x[0], cr.fetchall()) + # if the o2m has a static domain we must respect it when unlinking + domain = (self._domain(original_obj) + if callable(self._domain) else self._domain) + extra_domain = domain or [] + ids3 = obj.search(cr, user, [(self._fields_id,'=',id), ('id','not in',ids2)] + extra_domain, context=context) + # If the model has cascade deletion, we delete the rows because it is the intended behavior, + # otherwise we only nullify the reverse foreign key column. inverse_field = obj._fields.get(self._fields_id) if getattr(inverse_field, "ondelete", None) == "cascade": obj.unlink(cr, user, ids3, context=context)