[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:
@@ -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):
|
||||
|
||||
Reference in New Issue
Block a user