[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:
Raphael Collet
2022-03-11 20:36:12 +00:00
parent 8bd94f422f
commit b08676389c
2 changed files with 22 additions and 9 deletions
@@ -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
View File
@@ -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):