[FIX] base: do not assign default ondelete policy for base fields

Previously, an ondelete policy would be assigned to any required
Selection fields, the default policy being 'set null'.

Base fields do **not** require an ondelete value, since if they are
deleted there is no "data fix" to apply because the field's column is
dropped, and in fact it's error-prone to do so because during
`_process_ondelete`, the system would attempt to set to null fields that
were required (i.e. NOT NULL).

This issue is hidden by the fact that ir.model.fields are usually
deleted **before** ir.model.fields.selection and thus the ondelete
action won't be applied on the field with the original definition
(because it has probably been deleted by SQL CASCADE)

X-original-commit: 2e238f1e0202d65a98177939dac166dd659bb39c
This commit is contained in:
Adrian Torres
2021-03-10 16:45:06 +00:00
parent 8d61757be5
commit 75243d5a43
2 changed files with 19 additions and 2 deletions
+9 -2
View File
@@ -1381,8 +1381,15 @@ class IrModelSelection(models.Model):
if not field or not field.store or Model._abstract:
continue
ondelete = (field.ondelete or {}).get(selection.value) or 'set null'
if callable(ondelete):
ondelete = (field.ondelete or {}).get(selection.value)
# special case for custom fields
if ondelete is None and field.manual and not field.required:
ondelete = 'set null'
if ondelete is None:
# nothing to do, the selection does not come from a field extension
continue
elif callable(ondelete):
ondelete(selection._get_records())
elif ondelete == 'set null':
selection._get_records().write({field.name: False})
@@ -3056,6 +3056,16 @@ class TestSelectionOndelete(common.TransactionCase):
self.assertFalse(rec.my_selection)
def test_required_base_selection_field(self):
# test that no ondelete action is executed on a required selection field that is not
# extended, only required fields that extend it with selection_add should
# have ondelete actions defined
rec = self.env[self.MODEL_REQUIRED].create({'my_selection': 'foo'})
self.assertEqual(rec.my_selection, 'foo')
self._unlink_option(self.MODEL_REQUIRED, 'foo')
self.assertEqual(rec.my_selection, 'foo')
@common.tagged('selection_ondelete_advanced')
class TestSelectionOndeleteAdvanced(common.TransactionCase):