[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:
@@ -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
@@ -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)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user