[FIX] base: proper unlink of abtract model

Context:
Since 7593b887df an entry of ir.model.fields.selection is created
for each entry in a selection field. This allow a more modular
approach of tagging entries with an external id and translating
selections in the module that defined the selection (and not the one
that defined the field)

Problem:
When removing a selection, every record that used this selection is
updated with a 'set null'.
This was also intented on abstract models that do not have a table.

To reproduce:

1. create two models:

class ModelA(models.Abstract):
  _name = 'abstract.a'
  select = fields.Selection([
    ('foo', 'Foo'),
    ('bar', 'Bar'),
  ])

class ModelB(models.Model):
   _name = 'model.b'
   _inherit = 'abstract.a'

2. update code and removes the key 'foo'
3. update the module
   -> error
   psycopg2.errors.UndefinedTable: relation "abstract_a" does not exist
   LINE 1: UPDATE "abstract_a" SET "select"=NULL WHERE "re...

When updating the values in db, only update on real models

closes odoo/odoo#48288

X-original-commit: 6b20a8241300ebfc185500eb64e210db755574a8
Signed-off-by: Martin Trigaux (mat) <mat@odoo.com>
Signed-off-by: Christophe Monniez (moc) <moc@odoo.com>
This commit is contained in:
Martin Trigaux
2020-03-24 20:53:36 +00:00
parent 7da747c627
commit b51129bd30
3 changed files with 26 additions and 1 deletions
+2 -1
View File
@@ -1239,7 +1239,8 @@ class IrModelSelection(models.Model):
'preferably through a custom addon!'))
for selection in self:
if selection.field_id.store:
if selection.field_id.store and \
not self.env[selection.field_id.model]._abstract:
# replace the value by NULL in the field's corresponding column
query = 'UPDATE "{table}" SET "{field}"=NULL WHERE "{field}"=%s'.format(
table=self.env[selection.field_id.model]._table,
@@ -845,3 +845,14 @@ class City(models.Model):
name = fields.Char()
country_id = fields.Many2one('test_new_api.country')
# abstract model with a selection field
class StateMixin(models.AbstractModel):
_name = 'test_new_api.state_mixin'
_description = 'Dummy state mixin model'
state = fields.Selection([
('draft', 'Draft'),
('confirmed', 'Confirmed'),
('done', 'Done'),
])
@@ -2428,3 +2428,16 @@ class TestMany2oneReference(common.TransactionCase):
# fake record to emulate the unlink of a non-existant record
foo = m.browse(1 if not ids[0] else (ids[0] + 1))
self.assertTrue(foo.unlink())
@common.tagged('selection_abstract')
class TestSelectionDeleteUpdate(common.TransactionCase):
MODEL_ABSTRACT = 'test_new_api.state_mixin'
def test_unlink_asbtract(self):
self.env['ir.model.fields.selection'].search([
('field_id.model', '=', self.MODEL_ABSTRACT),
('field_id.name', '=', 'state'),
('value', '=', 'confirmed'),
], limit=1).unlink()