From 96a98f4f4c9885ced0d44829341a951ca4a963c5 Mon Sep 17 00:00:00 2001 From: Raphael Collet Date: Mon, 17 Jul 2023 15:53:53 +0000 Subject: [PATCH] [FIX] web: web_read() on new records with _inherits This commit partly reverts 59afbf6686bcbdfa5d31b09303ce295dbed13bea and provides an alternative solution. In this solution, records.web_read() returns a list of dicts where the key 'id' corresponds to each record.id in records, which enables to reliably relate each record to its values. This also fixes the implementation of web_read() on new records where the fields contain a reference field with some context. closes odoo/odoo#128878 Signed-off-by: Raphael Collet --- addons/web/models/models.py | 14 +++++++---- .../test_new_api/tests/test_unity_read.py | 24 +++++++++++++++++-- odoo/fields.py | 2 ++ odoo/models.py | 2 +- 4 files changed, 35 insertions(+), 7 deletions(-) diff --git a/addons/web/models/models.py b/addons/web/models/models.py index f8087a619be..240eddf7b9c 100644 --- a/addons/web/models/models.py +++ b/addons/web/models/models.py @@ -90,13 +90,19 @@ class Base(models.AbstractModel): if fields_to_read == ['id']: # if we request to read only the ids, we have them already so we can build the return dictionaries immediately # this also avoid a call to read on the co-model that might have different access rules - values_list = [{'id': record._origin.id} for record in self] + values_list = [{'id': id_} for id_ in self._ids] else: values_list: List[Dict] = self.read(fields_to_read, load=None) if not values_list: return values_list + def cleanup(vals: Dict) -> Dict: + """ Fixup vals['id'] of a new record. """ + if not vals['id']: + vals['id'] = vals['id'].origin or False + return vals + for field_name, field_spec in specification.items(): if not field_spec: continue @@ -111,16 +117,16 @@ class Base(models.AbstractModel): extra_fields.pop('display_name', None) many2one_data = { - vals['id']: vals + vals['id']: cleanup(vals) for vals in co_records.web_read(extra_fields) } if 'display_name' in field_spec['fields']: for rec in co_records.sudo(): - many2one_data[rec._origin.id]['display_name'] = rec.display_name + many2one_data[rec.id]['display_name'] = rec.display_name for values in values_list: - if not values[field_name]: + if values[field_name] is False: continue values[field_name] = many2one_data[values[field_name]] diff --git a/odoo/addons/test_new_api/tests/test_unity_read.py b/odoo/addons/test_new_api/tests/test_unity_read.py index ed46c88c159..3fe3f3c67a2 100644 --- a/odoo/addons/test_new_api/tests/test_unity_read.py +++ b/odoo/addons/test_new_api/tests/test_unity_read.py @@ -164,7 +164,7 @@ class TestUnityRead(TransactionCase): 'login': {}, }) self.assertEqual(result, [{ - 'id': new_account._origin.id, + 'id': new_account.id, 'name': new_account.name, 'login': new_account.login, }]) @@ -176,7 +176,7 @@ class TestUnityRead(TransactionCase): 'person_id': {'fields': {'name': {}}}, }) self.assertEqual(result, [{ - 'id': new_account._origin.id, + 'id': new_account.id, 'person_id': { 'id': new_account.person_id._origin.id, 'name': new_account.person_id.name, @@ -561,6 +561,26 @@ class TestUnityRead(TransactionCase): } ]) + def test_reference_fields_respect_context_with_new_record(self): + new_course = self.course.new(origin=self.course) + read = new_course.web_read( + { + 'reference': + { + 'fields': {'display_name': {}}, + 'context': {'special': 'yes'} + } + }) + self.assertEqual(read, [ + { + 'id': new_course.id, + 'reference': { + 'id': {'id': self.lesson_day1.id, 'model': self.lesson_day1._name}, + 'display_name': 'special first day' + } + } + ]) + def test_reference_fields_extra_fields(self): read = self.course.web_read( { diff --git a/odoo/fields.py b/odoo/fields.py index 216904d383c..09da59f98d4 100644 --- a/odoo/fields.py +++ b/odoo/fields.py @@ -3037,6 +3037,8 @@ class Many2one(_Relational): except MissingError: # Should not happen, unless the foreign key is missing. return False + elif self.delegate: + return value.id else: return value._origin.id diff --git a/odoo/models.py b/odoo/models.py index 49996a1cb83..c70abcd5f73 100644 --- a/odoo/models.py +++ b/odoo/models.py @@ -3355,7 +3355,7 @@ class BaseModel(metaclass=MetaModel): The current method is different from `read` because it retrieves its values from the cache without doing a query when it is avoidable. """ - data = [(record, {'id': record._origin.id}) for record in self] + data = [(record, {'id': record.id}) for record in self] use_display_name = (load == '_classic_read') for name in fnames: field = self._fields[name]