[FIX] fields: ondelete being None on many2many field
The issue is simply creating a related stored many2many field, which is
pretty easy to do with Studio. When creating the field, Odoo crashes
with a traceback caused by ondelete being None on the field.
The source of the bug is the fact that the attribute field.ondelete is
set to a sensible default ('cascade') on non-related fields only. The
fix consists in setting the default value on the attribute itself, so
that the setup of the field never falls on a case where field.ondelete
is unset.
closes odoo/odoo#86303
X-original-commit: d0e0d80806a1b63ac986e9bcbaf88f9fc5243319
Signed-off-by: Raphael Collet <rco@odoo.com>
This commit is contained in:
@@ -2878,6 +2878,21 @@ class TestX2many(common.TransactionCase):
|
||||
})
|
||||
self.assertTrue(field.unlink())
|
||||
|
||||
def test_custom_m2m_related(self):
|
||||
# this checks the ondelete of a related many2many field
|
||||
model_id = self.env['ir.model']._get_id('res.partner')
|
||||
field = self.env['ir.model.fields'].create({
|
||||
'name': 'x_foo',
|
||||
'field_description': 'Foo',
|
||||
'model_id': model_id,
|
||||
'ttype': 'many2many',
|
||||
'relation': 'res.partner.category',
|
||||
'related': 'category_id',
|
||||
'readonly': True,
|
||||
'store': True,
|
||||
})
|
||||
self.assertTrue(field.unlink())
|
||||
|
||||
|
||||
class TestHtmlField(common.TransactionCase):
|
||||
|
||||
|
||||
+7
-9
@@ -3720,7 +3720,7 @@ class Many2many(_RelationalMulti):
|
||||
column1 = None # column of table referring to model
|
||||
column2 = None # column of table referring to comodel
|
||||
auto_join = False # whether joins are generated upon search
|
||||
ondelete = None # optional ondelete for the column2 fkey
|
||||
ondelete = 'cascade' # optional ondelete for the column2 fkey
|
||||
|
||||
def __init__(self, comodel_name=Default, relation=Default, column1=Default,
|
||||
column2=Default, string=Default, **kwargs):
|
||||
@@ -3735,17 +3735,15 @@ class Many2many(_RelationalMulti):
|
||||
|
||||
def setup_nonrelated(self, model):
|
||||
super().setup_nonrelated(model)
|
||||
# 3 cases:
|
||||
# 1) The ondelete attribute is not defined, we assign it a sensible default
|
||||
# 2) The ondelete attribute is defined and its definition makes sense
|
||||
# 3) The ondelete attribute is explicitly defined as 'set null' for a m2m,
|
||||
# 2 cases:
|
||||
# 1) The ondelete attribute is defined and its definition makes sense
|
||||
# 2) The ondelete attribute is explicitly defined as 'set null' for a m2m,
|
||||
# this is considered a programming error.
|
||||
self.ondelete = self.ondelete or 'cascade'
|
||||
if self.ondelete == 'set null':
|
||||
if self.ondelete not in ('cascade', 'restrict'):
|
||||
raise ValueError(
|
||||
"The m2m field %s of model %s declares its ondelete policy "
|
||||
"as being 'set null'. Only 'restrict' and 'cascade' make sense."
|
||||
% (self.name, model._name)
|
||||
"as being %r. Only 'restrict' and 'cascade' make sense."
|
||||
% (self.name, model._name, self.ondelete)
|
||||
)
|
||||
if self.store:
|
||||
if not (self.relation and self.column1 and self.column2):
|
||||
|
||||
Reference in New Issue
Block a user