[FIX] fields: make [(5,)] with computed domain work (#13480)

* Failing test for one2many [(5,)] action, when domain is callable.

The problem is that `self` inside a callable domain becomes the comodel when at [(5,)].

* [FIX][fields] Make [(5,)] with computed domain work.

To reproduce this failure, declare a field like:

```
child_ids = fields.One2many(
    comodel_name="other.model",
    domain=lambda self: [("id", "in", self._ids_to_find())],
)
```

Now set some value to it.

Now unset them. Impossible because ``self`` becomes ``other.model`` in domain evaluation.
This commit is contained in:
Jairo Llopis 2016-10-11 15:14:05 +02:00 committed by Raphael Collet
parent 633780a00c
commit dd312e0da2
3 changed files with 16 additions and 1 deletions

View File

@ -145,10 +145,17 @@ class Discussion(models.Model):
message_changes = fields.Integer(string='Message changes')
important_messages = fields.One2many('test_new_api.message', 'discussion',
domain=[('important', '=', True)])
very_important_messages = fields.One2many(
'test_new_api.message', 'discussion',
domain=lambda self: self._domain_very_important())
emails = fields.One2many('test_new_api.emailmessage', 'discussion')
important_emails = fields.One2many('test_new_api.emailmessage', 'discussion',
domain=[('important', '=', True)])
def _domain_very_important(self):
"""Ensure computed O2M domains work as expected."""
return [("important", "=", True)]
@api.onchange('moderator')
def _onchange_moderator(self):
self.participants |= self.moderator

View File

@ -470,6 +470,12 @@ class TestNewFields(common.TransactionCase):
message.important = True
self.assertIn(message, discussion.important_messages)
# writing on very_important_messages should call its domain method
self.assertIn(message, discussion.very_important_messages)
discussion.write({'very_important_messages': [(5,)]})
self.assertFalse(discussion.very_important_messages)
self.assertFalse(message.exists())
class TestMagicFields(common.TransactionCase):

View File

@ -788,6 +788,7 @@ class one2many(_column):
context.update(self._context)
if not values:
return
original_obj = obj
obj = obj.pool[self._obj]
rec = obj.browse(cr, user, [], context=context)
with rec.env.norecompute():
@ -819,7 +820,8 @@ class one2many(_column):
inverse_field = obj._fields.get(self._fields_id)
assert inverse_field, 'Trying to unlink the content of a o2m but the pointed model does not have a m2o'
# if the o2m has a static domain we must respect it when unlinking
domain = self._domain(obj) if callable(self._domain) else self._domain
domain = (self._domain(original_obj)
if callable(self._domain) else self._domain)
extra_domain = domain or []
ids_to_unlink = obj.search(cr, user, [(self._fields_id,'=',id)] + extra_domain, context=context)
# If the model has cascade deletion, we delete the rows because it is the intended behavior,