[FIX] website: skip view's copy-on-write when updating translations

Since [1] when the translations were converted to jsonb, when
translations are saved, the actual `ir.ui.view` is saved (instead of a
translation record like before). Because of this, the copy-on-write
mechanism of `website` kicks in and unneeded website-specific views are
created.

This commit disables the copy-on-write mechanism during the update of
translations in views.

Steps to reproduce:
- Install `website_sale`.
- Install a second language (e.g. French).
- Go to a single product's website page in the second language.
- Translate the "ADD TO CART" button.

=> Many website-specific views were created.

[1]: https://github.com/odoo/odoo/commit/4e82c45abdb0b420edead2bd1d0ba9ff4bb4a224

task-3225622

closes odoo/odoo#117256

X-original-commit: 1bf7e2322d22aeef30097a1d19848ff351bc83f9
Signed-off-by: Quentin Smetz (qsm) <qsm@odoo.com>
This commit is contained in:
Benoit Socias
2023-03-31 15:52:37 +02:00
parent 7e19621fbc
commit 0f8bd89331
2 changed files with 23 additions and 0 deletions
+3
View File
@@ -503,3 +503,6 @@ class View(models.Model):
if website_id:
res['website_id'] = website_id
return res
def _update_field_translations(self, fname, translations, digest=None):
return super(View, self.with_context(no_cow=True))._update_field_translations(fname, translations, digest)
+20
View File
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from hashlib import sha256
import unittest
from itertools import zip_longest
from lxml import etree as ET, html
@@ -1130,6 +1131,25 @@ class TestCowViewSaving(TestViewSavingCommon):
self.assertTrue(self.inherit_view in base_view_2.inherit_children_ids, "D should be under B")
self.assertTrue(specific_child_view in base_view_2.inherit_children_ids, "D' should be under B")
def test_no_cow_on_translate(self):
french = self.env['res.lang']._activate_lang('fr_FR')
self.env['ir.module.module']._load_module_terms(['website'], [french.code])
# Make sure res.lang.get_installed is recomputed
self.env.registry.clear_caches()
View = self.env['ir.ui.view'].with_context(lang=french.code, website_id=1)
old_specific_views = View.search([('website_id', '!=', None)])
view = self.base_view.with_context(lang=french.code, website_id=1)
root = html.fromstring(self.base_view.arch, parser=html.HTMLParser(encoding="utf-8"))
to_translate = root.text_content()
sha = sha256(to_translate.encode()).hexdigest()
view.update_field_translations_sha('arch_db', {french.code: {sha: 'contenu de base'}})
new_specific_views = View.search([('website_id', '!=', None)])
self.assertEqual(len(old_specific_views), len(new_specific_views), "No additional specific view must have been created")
self.assertTrue(view.arch.index('contenu de base') > 0, "New translation must appear in view")
@tagged('-at_install', 'post_install')
class Crawler(HttpCase):