[IMP] base: do not write in database when we have invalid properties names

Purpose
=======
When we create a new record, we can change the definition on the definition
record. If the parent had no definition, in `_add_default_values`,
we just return the value. But in some weird cases, if we have
invalid properties name in the value, the will be written in database.

Now, in that particular case, we propagate the value only
if we try to change the definition.

Part-of: odoo/odoo#120457
This commit is contained in:
std-odoo
2023-05-05 18:08:09 +02:00
committed by Raphael Collet
parent 7a5f655879
commit dc95819257
2 changed files with 55 additions and 4 deletions
@@ -92,7 +92,7 @@ class TestPropertiesMixin(TransactionCase):
""", (message.id, ),
)
value = self.env.cr.fetchone()
self.assertTrue(value and value[0])
self.assertTrue(value)
return value[0]
def _get_sql_definition(self, discussion):
@@ -530,6 +530,51 @@ class PropertiesCase(TestPropertiesMixin):
msg='Should not take the default value',
)
# default value but no parent are set
record = self.env['test_new_api.message'].create({
'attributes': {'my_many2one': self.partner_2.id},
})
self.assertFalse(self._get_sql_properties(record))
# default value but the parent has no definition
self.discussion_1.attributes_definition = []
record = self.env['test_new_api.message'].create({
'discussion': self.discussion_1.id,
'attributes': {'my_many2one': self.partner_2.id},
})
self.assertFalse(self._get_sql_properties(record))
# default value but the parent has no definition and we create a new property
self.discussion_1.attributes_definition = []
record = self.env['test_new_api.message'].create({
'discussion': self.discussion_1.id,
'attributes': [{
'name': 'test',
'type': 'many2one',
'comodel': 'test_new_api.partner',
'default': self.partner_2.id,
'definition_changed': True,
}],
})
self.assertEqual(self._get_sql_properties(record), {'test': self.partner_2.id})
# default value, a parent is set and change the definition
record = self.env['test_new_api.message'].create({
'discussion': self.discussion_1.id,
'attributes': [{
'name': 'test',
'type': 'many2one',
'comodel': 'test_new_api.partner',
'default': self.partner_2.id,
}, {
'name': 'my_char',
'type': 'char',
'default': 'my char',
'definition_changed': True,
}],
})
self.assertEqual(self._get_sql_properties(record), {'my_char': 'my char', 'test': self.partner_2.id})
def test_properties_field_read(self):
"""Test the behavior of the read method.
+9 -3
View File
@@ -3442,7 +3442,7 @@ class Properties(Field):
if not values.get(self.definition_record):
# container is not given in the value, can not find properties definition
return properties_values
return {}
container_id = values[self.definition_record]
if not isinstance(container_id, (int, BaseModel)):
@@ -3456,8 +3456,14 @@ class Properties(Field):
container_id = env[container_model_name].browse(container_id)
properties_definition = container_id[self.definition_record_field]
if not properties_definition:
return properties_values
if not (properties_definition or (
isinstance(properties_values, list)
and any(d.get('definition_changed') for d in properties_values)
)):
# If a parent is set without properties, we might want to change its definition
# when we create the new record. But if we just set the value without changing
# the definition, in that case we can just ignored the passed values
return {}
assert isinstance(properties_values, (list, dict))
if isinstance(properties_values, list):