[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:
parent
633780a00c
commit
dd312e0da2
|
@ -145,10 +145,17 @@ class Discussion(models.Model):
|
||||||
message_changes = fields.Integer(string='Message changes')
|
message_changes = fields.Integer(string='Message changes')
|
||||||
important_messages = fields.One2many('test_new_api.message', 'discussion',
|
important_messages = fields.One2many('test_new_api.message', 'discussion',
|
||||||
domain=[('important', '=', True)])
|
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')
|
emails = fields.One2many('test_new_api.emailmessage', 'discussion')
|
||||||
important_emails = fields.One2many('test_new_api.emailmessage', 'discussion',
|
important_emails = fields.One2many('test_new_api.emailmessage', 'discussion',
|
||||||
domain=[('important', '=', True)])
|
domain=[('important', '=', True)])
|
||||||
|
|
||||||
|
def _domain_very_important(self):
|
||||||
|
"""Ensure computed O2M domains work as expected."""
|
||||||
|
return [("important", "=", True)]
|
||||||
|
|
||||||
@api.onchange('moderator')
|
@api.onchange('moderator')
|
||||||
def _onchange_moderator(self):
|
def _onchange_moderator(self):
|
||||||
self.participants |= self.moderator
|
self.participants |= self.moderator
|
||||||
|
|
|
@ -470,6 +470,12 @@ class TestNewFields(common.TransactionCase):
|
||||||
message.important = True
|
message.important = True
|
||||||
self.assertIn(message, discussion.important_messages)
|
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):
|
class TestMagicFields(common.TransactionCase):
|
||||||
|
|
||||||
|
|
|
@ -788,6 +788,7 @@ class one2many(_column):
|
||||||
context.update(self._context)
|
context.update(self._context)
|
||||||
if not values:
|
if not values:
|
||||||
return
|
return
|
||||||
|
original_obj = obj
|
||||||
obj = obj.pool[self._obj]
|
obj = obj.pool[self._obj]
|
||||||
rec = obj.browse(cr, user, [], context=context)
|
rec = obj.browse(cr, user, [], context=context)
|
||||||
with rec.env.norecompute():
|
with rec.env.norecompute():
|
||||||
|
@ -819,7 +820,8 @@ class one2many(_column):
|
||||||
inverse_field = obj._fields.get(self._fields_id)
|
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'
|
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
|
# 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 []
|
extra_domain = domain or []
|
||||||
ids_to_unlink = obj.search(cr, user, [(self._fields_id,'=',id)] + extra_domain, context=context)
|
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,
|
# If the model has cascade deletion, we delete the rows because it is the intended behavior,
|
||||||
|
|
Loading…
Reference in New Issue