From 19bd80758b053b8d89e0a58bbac42d3e02b3ebb5 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Mon, 30 Nov 2020 10:48:29 +0000 Subject: [PATCH] [FIX] core: avoid multiple calls to default_get() in onchange Upon the first call to `onchange`, the `values` dict is filled with default values. But the fields without a default are left unassigned. This allows to compute fields when accessing them, but non-computed fields will ask again for their default value, which is a waste of time because we know they don't have one. This may even be a performance issue on forms with many fields. Fix this issue by completing `values` with falsy values, and consider the fields with some initial value (given or default) as the assigned ones for triggering onchanges. This explicitly triggers the computation of fields that depend on fields with some initial value, without forcing them to `False`. Also avoid accessing x2many fields on the record in `snapshot.diff()`. Enable the prefetching by simply putting the right value in cache. closes odoo/odoo#62844 X-original-commit: 80c1dad6d9124da9459ce38d9e8c03e5c461c180 Signed-off-by: Raphael Collet (rco) --- odoo/models.py | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/odoo/models.py b/odoo/models.py index 84e4b16b399..fba69554872 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -6056,7 +6056,9 @@ Fields: # diff(), therefore evaluating line._prefetch_ids with an empty # cache simply returns nothing, which discards the prefetching # optimization! - record[name] + record._cache[name] = tuple( + line_snapshot[''].id for line_snapshot in self[name] + ) for line_snapshot in self[name]: line = line_snapshot[''] line = line._origin or line @@ -6080,11 +6082,13 @@ Fields: nametree = PrefixTree(self.browse(), field_onchange) if first_call: - values.update(self.default_get([ - name - for name in nametree - if name not in values - ])) + names = [name for name in values if name != 'id'] + missing_names = [name for name in nametree if name not in values] + defaults = self.default_get(missing_names) + for name in missing_names: + values[name] = defaults.get(name, False) + if name in defaults: + names.append(name) # prefetch x2many lines: this speeds up the initial snapshot by avoiding # to compute fields on new records as much as possible, as that can be