[FIX] core: partial unlink in recordset

The following loop crashes on the second iteration:

    for record in records:
	record.display_name     # access non-stored computed field
        record.unlink()         # delete record

The cache has been invalidated by `unlink` on the first iteration, so
the field is computed.  The computation is done on the whole recordset,
which fails with a `MissingError` because of the first record.  The fix
is to retry the recomputation on the single record in this case.

closes odoo/odoo#50910

X-original-commit: 7f33ebf528b1415452ce549e3329c3fe89be0ad8
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
Raphael Collet
2020-05-08 11:33:38 +00:00
parent 12c6eba844
commit 5fc9b8c44a
2 changed files with 20 additions and 2 deletions
+18
View File
@@ -35,6 +35,24 @@ class TestORM(TransactionCase):
# Deleting an already deleted record should be simply ignored
self.assertTrue(p1.unlink(), "Re-deleting should be a no-op")
@mute_logger('odoo.models')
def test_access_partial_deletion(self):
""" Check accessing a record from a recordset where another record has been deleted. """
Model = self.env['res.country']
self.assertTrue(type(Model).display_name.automatic, "test assumption not satisfied")
# access regular field when another record from the same prefetch set has been deleted
records = Model.create([{'name': name} for name in ('Foo', 'Bar', 'Baz')])
for record in records:
record.name
record.unlink()
# access computed field when another record from the same prefetch set has been deleted
records = Model.create([{'name': name} for name in ('Foo', 'Bar', 'Baz')])
for record in records:
record.display_name
record.unlink()
@mute_logger('odoo.models', 'odoo.addons.base.models.ir_rule')
def test_access_filtered_records(self):
""" Verify that accessing filtered records works as expected for non-admin user """
+2 -2
View File
@@ -914,7 +914,7 @@ class Field(MetaField('DummyField', (object,), {})):
recs = record if self.recursive else env.records_to_compute(self)
try:
self.compute_value(recs)
except AccessError:
except (AccessError, MissingError):
self.compute_value(record)
try:
@@ -949,7 +949,7 @@ class Field(MetaField('DummyField', (object,), {})):
recs = record if self.recursive else record._in_cache_without(self)
try:
self.compute_value(recs)
except AccessError:
except (AccessError, MissingError):
self.compute_value(record)
value = env.cache.get(record, self)