[FIX] base: handle custom non-stored m2m

Before this commit, one could create a custom, non-stored m2m field
through the web interface BUT the deletion of the custom field would be
impossible after saving the form.

This is due to the fact that the relation would not be stored in DB
since the field is store=False, therefore the value of the relation
would equal to None, and since the unlinking mechanism assumes that
the value is never None, it tries to drop a table of name None, which
does not exist.

closes odoo/odoo#46909

X-original-commit: cdd1439a380810569db80d984c8cb80d213b1bf3
Signed-off-by: Adrian Torres (adt) <adt@odoo.com>
This commit is contained in:
Adrian Torres
2020-03-04 15:39:18 +00:00
parent babf9e4f2c
commit 26680badef
2 changed files with 22 additions and 6 deletions
+10 -6
View File
@@ -623,12 +623,16 @@ class IrModelFields(models.Model):
continue
model = self.env.get(field.model)
is_model = model is not None
if is_model and tools.column_exists(self._cr, model._table, field.name) and \
tools.table_kind(self._cr, model._table) == 'r':
self._cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE' % (model._table, field.name))
if field.state == 'manual' and field.ttype == 'many2many':
rel_name = field.relation_table or (is_model and model._fields[field.name].relation)
tables_to_drop.add(rel_name)
if field.store:
# TODO: Refactor this brol in master
if is_model and tools.column_exists(self._cr, model._table, field.name) and \
tools.table_kind(self._cr, model._table) == 'r':
self._cr.execute('ALTER TABLE "%s" DROP COLUMN "%s" CASCADE' % (
model._table, field.name,
))
if field.state == 'manual' and field.ttype == 'many2many':
rel_name = field.relation_table or (is_model and model._fields[field.name].relation)
tables_to_drop.add(rel_name)
if field.state == 'manual' and is_model:
model._pop_field(field.name)
if field.translate:
@@ -2037,6 +2037,18 @@ class TestX2many(common.TransactionCase):
for line in lines:
self.assertEqual(len(line.tags), 3)
def test_custom_m2m(self):
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.country',
'store': False,
})
self.assertTrue(field.unlink())
class TestHtmlField(common.TransactionCase):