[FIX] web: onchange() does not handle _inherits parent field in one2many

Consider models A and B such that B inherits from A (with _inherits),
and a form view of A with a one2many field that inverses the many2one
"delegate" field from B to A.  When adding a new record in the one2many,
onchange() crashes while trying to update the cache of an empty parent
record.

The situation is caused by how onchange() initializes the new record of
model B, and the fact that the form provides a value for the delegate
field.  The new record is actually initialized with an empty value for
the delegate field, which causes the code to crash.  The fix simply
consists in updating the parent record only if is nonempty.

opw-3744514

closes odoo/odoo#154735

Signed-off-by: Rémy Voet (ryv) <ryv@odoo.com>
Co-authored-by: Lucas Perais <lpe@odoo.com>
This commit is contained in:
Raphael Collet
2024-02-20 14:57:35 +00:00
co-authored by Lucas Perais
parent 1ae849a7e2
commit 15bfff301c
2 changed files with 26 additions and 1 deletions
+2 -1
View File
@@ -1018,7 +1018,8 @@ class Base(models.AbstractModel):
field = self._fields.get(field_name)
if field and field.inherited:
parent_name, field_name = field.related.split('.', 1)
record[parent_name]._update_cache({field_name: record[field_name]})
if parent := record[parent_name]:
parent._update_cache({field_name: record[field_name]})
# make a snapshot based on the initial values of record
snapshot0 = RecordSnapshot(record, fields_spec, fetch=(not first_call))
@@ -685,6 +685,30 @@ class TestOnchange(SavepointCaseWithUserDemo):
self.assertEqual(payment.tag_repeat, 3)
self.assertEqual(payment.tag_string, 'BarBarBar')
def test_onchange_inherited_in_one2many(self):
move = self.env['test_new_api.move'].create({})
view = self.env["ir.ui.view"].create({
"model": "test_new_api.move",
"type": "form",
"arch": """<form>
<field name="payment_ids">
<form>
<!-- tag_repeat is inherited from move model -->
<field name="tag_repeat" />
</form>
</field>
</form>"""
})
with Form(move, view) as form:
with form.payment_ids.new() as line:
line.tag_repeat = 1
self.assertEqual(len(form.payment_ids), 1)
self.assertEqual(len(move.payment_ids), 1)
self.assertEqual(move.payment_ids.move_id, move)
self.assertEqual(move.payment_ids.tag_repeat, 1)
def test_display_name(self):
self.env['ir.ui.view'].create({
'name': 'test_new_api.multi.tag form view',