[FIX] core: avoid invalidation of field 'ir.ui.view.arch' when setting it

This fixes the following issue.  Set the field `arch` on a view; this
automatically writes on `arch_db`, which is a translated field.  If some
translations are discarded, a call to `unlink()` invalidates the whole
cache.  And then things go wrong: when `arch_db` is validated, the field
`arch` is missing from cache, and the ORM sets it to `None` because the
field is still protected by the initial write!

Fix the issue by avoiding the call to `unlink()`, and do it in SQL
instead.

closes odoo/odoo#45740

X-original-commit: e7679152ee480a51ef2b6d208ae7a05b2ef61941
Signed-off-by: Raphael Collet (rco) <rco@openerp.com>
This commit is contained in:
Raphael Collet
2020-02-19 17:42:16 +00:00
parent b293ccc7c3
commit 60b0f6da34
2 changed files with 34 additions and 1 deletions
+8 -1
View File
@@ -445,7 +445,14 @@ class IrTranslation(models.Model):
# process outdated and discarded translations
outdated.write({'state': 'to_translate'})
discarded.unlink()
if discarded:
# delete in SQL to avoid invalidating the whole cache
discarded._modified()
discarded.modified(self._fields)
self.flush(self._fields, discarded)
self.invalidate_cache(ids=discarded._ids)
self.env.cr.execute("DELETE FROM ir_translation WHERE id IN %s", [discarded._ids])
@api.model
@tools.ormcache_context('model_name', keys=('lang',))
+26
View File
@@ -236,6 +236,32 @@ class TestViewInheritance(ViewCase):
'arch': self.arch_for('itself', parent=True),
})
def test_write_arch(self):
self.env['res.lang']._activate_lang('fr_FR')
v = self.makeView("T", arch='<form string="Foo">Bar</form>')
self.env['ir.translation']._upsert_translations([{
'type': 'model_terms',
'name': 'ir.ui.view,arch_db',
'lang': 'fr_FR',
'res_id': v.id,
'src': 'Foo',
'value': 'Fou',
}, {
'type': 'model_terms',
'name': 'ir.ui.view,arch_db',
'lang': 'fr_FR',
'res_id': v.id,
'src': 'Bar',
'value': 'Barre',
}])
self.assertEqual(v.arch, '<form string="Foo">Bar</form>')
# modify v to discard translations; this should not invalidate 'arch'!
v.arch = '<form></form>'
self.assertEqual(v.arch, '<form></form>')
class TestApplyInheritanceSpecs(ViewCase):
""" Applies a sequence of inheritance specification nodes to a base
architecture. IO state parameters (cr, uid, model, context) are used for