[FIX] web: web_read() on new records with _inherits

Part-of: odoo/odoo#127718
This commit is contained in:
Raphael Collet
2023-07-10 18:16:19 +02:00
parent b3e8560c9c
commit 59afbf6686
5 changed files with 56 additions and 3 deletions
+2 -2
View File
@@ -90,7 +90,7 @@ 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': id_} for id_ in self._ids]
values_list = [{'id': record._origin.id} for record in self]
else:
values_list: List[Dict] = self.read(fields_to_read, load=None)
@@ -117,7 +117,7 @@ class Base(models.AbstractModel):
if 'display_name' in field_spec['fields']:
for rec in co_records.sudo():
many2one_data[rec.id]['display_name'] = rec.display_name
many2one_data[rec._origin.id]['display_name'] = rec.display_name
for values in values_list:
if not values[field_name]:
@@ -1,5 +1,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo import models, fields
class Course(models.Model):
_name = 'test_new_api.course'
_description = 'a course'
@@ -15,6 +18,7 @@ class Course(models.Model):
def _selection_reference_model(self):
return [('test_new_api.lesson', None)]
class Lesson(models.Model):
_name = 'test_new_api.lesson'
_description = 'a lesson of a course (a day typically)'
@@ -35,6 +39,7 @@ class Lesson(models.Model):
else:
record.display_name = record.name
class Person(models.Model):
_name = 'test_new_api.person'
_description = 'a person, can be an author, teacher or attendee of a lesson'
@@ -52,9 +57,19 @@ class Person(models.Model):
for record in self:
record.display_name = f"{particular}{record.name}{special}"
class Employer(models.Model):
_name = 'test_new_api.employer'
_description = 'the employer of a person'
name = fields.Char('Name')
employee_ids = fields.One2many('test_new_api.person', 'employer_id')
class PersonAccount(models.Model):
_name = 'test_new_api.person.account'
_description = 'an account with credentials for a given person'
_inherits = {'test_new_api.person': 'person_id'}
person_id = fields.Many2one('test_new_api.person', required=True, ondelete='cascade')
login = fields.Char()
@@ -106,6 +106,7 @@ access_test_new_api_course,access_test_new_api_course,model_test_new_api_course,
access_test_new_api_lesson,access_test_new_api_lesson,model_test_new_api_lesson,base.group_user,1,1,1,1
access_test_new_api_person,access_test_new_api_person,model_test_new_api_person,base.group_user,1,1,1,1
access_test_new_api_employer,access_test_new_api_employer,model_test_new_api_employer,base.group_user,1,1,1,1
access_test_new_api_person_account,access_test_new_api_person_account,model_test_new_api_person_account,base.group_user,1,1,1,1
public_access_test_new_api_course,access_test_new_api_course,model_test_new_api_course,base.group_public,1,0,0,0
access_test_new_api_team,access_test_new_api_team,model_test_new_api_team,base.group_user,1,0,0,0
access_test_new_api_team_member,access_test_new_api_team_member,model_test_new_api_team_member,base.group_user,1,0,0,0
1 id name model_id:id group_id:id perm_read perm_write perm_create perm_unlink
106 access_test_new_api_lesson access_test_new_api_lesson model_test_new_api_lesson base.group_user 1 1 1 1
107 access_test_new_api_person access_test_new_api_person model_test_new_api_person base.group_user 1 1 1 1
108 access_test_new_api_employer access_test_new_api_employer model_test_new_api_employer base.group_user 1 1 1 1
109 access_test_new_api_person_account access_test_new_api_person_account model_test_new_api_person_account base.group_user 1 1 1 1
110 public_access_test_new_api_course access_test_new_api_course model_test_new_api_course base.group_public 1 0 0 0
111 access_test_new_api_team access_test_new_api_team model_test_new_api_team base.group_user 1 0 0 0
112 access_test_new_api_team_member access_test_new_api_team_member model_test_new_api_team_member base.group_user 1 0 0 0
@@ -1,3 +1,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from dateutil.relativedelta import relativedelta
from odoo import Command, fields
@@ -14,6 +16,10 @@ class TestUnityRead(TransactionCase):
cls.only_course_user = new_test_user(cls.env, 'no acc', 'base.group_public')
cls.author = cls.env['test_new_api.person'].create({'name': 'ged'})
cls.teacher = cls.env['test_new_api.person'].create({'name': 'aab'})
cls.account = cls.env['test_new_api.person.account'].create({
'person_id': cls.teacher.id,
'login': 'aab',
})
cls.course = cls.env['test_new_api.course'].create({
'name': 'introduction to OWL',
'author_id': cls.author.id
@@ -146,6 +152,37 @@ class TestUnityRead(TransactionCase):
}
}])
def test_new_record_with_inherits(self):
# virtualize a record
new_account = self.account.new(origin=self.account)
self.assertTrue(new_account)
self.assertFalse(new_account.id)
# read the virtualized record; field 'id' corresponds to record's origin
result = new_account.web_read({
'name': {},
'login': {},
})
self.assertEqual(result, [{
'id': new_account._origin.id,
'name': new_account.name,
'login': new_account.login,
}])
# special case: read the many2one field of _inherits
self.assertTrue(new_account.person_id)
self.assertFalse(new_account.person_id.id)
result = new_account.web_read({
'person_id': {'fields': {'name': {}}},
})
self.assertEqual(result, [{
'id': new_account._origin.id,
'person_id': {
'id': new_account.person_id._origin.id,
'name': new_account.person_id.name,
},
}])
def test_multilevel_query_count(self):
author = self.env['test_new_api.person'].create({'name': 'AAA'})
teacher1 = self.env['test_new_api.person'].create({'name': 'BBB'})
+1 -1
View File
@@ -3354,7 +3354,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._ids[0]}) for record in self]
data = [(record, {'id': record._origin.id}) for record in self]
use_display_name = (load == '_classic_read')
for name in fnames:
field = self._fields[name]