From b51129bd304e74a5eef94fcabca915aedf56e5ad Mon Sep 17 00:00:00 2001 From: Martin Trigaux Date: Mon, 16 Mar 2020 09:06:16 +0000 Subject: [PATCH] [FIX] base: proper unlink of abtract model Context: Since 7593b887dff4f 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) Signed-off-by: Christophe Monniez (moc) --- odoo/addons/base/models/ir_model.py | 3 ++- odoo/addons/test_new_api/models/test_new_api.py | 11 +++++++++++ odoo/addons/test_new_api/tests/test_new_fields.py | 13 +++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/odoo/addons/base/models/ir_model.py b/odoo/addons/base/models/ir_model.py index 676c1061ed5..53ae02f6d5d 100644 --- a/odoo/addons/base/models/ir_model.py +++ b/odoo/addons/base/models/ir_model.py @@ -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, diff --git a/odoo/addons/test_new_api/models/test_new_api.py b/odoo/addons/test_new_api/models/test_new_api.py index 9331f6eedee..ad57c768d0e 100644 --- a/odoo/addons/test_new_api/models/test_new_api.py +++ b/odoo/addons/test_new_api/models/test_new_api.py @@ -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'), + ]) diff --git a/odoo/addons/test_new_api/tests/test_new_fields.py b/odoo/addons/test_new_api/tests/test_new_fields.py index 7aa9b3c5a74..8fee8359658 100644 --- a/odoo/addons/test_new_api/tests/test_new_fields.py +++ b/odoo/addons/test_new_api/tests/test_new_fields.py @@ -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()