From 0f8bd893312027e82d4c774ded1580e619743fbb Mon Sep 17 00:00:00 2001 From: Benoit Socias Date: Thu, 23 Mar 2023 14:03:27 +0000 Subject: [PATCH] [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) --- addons/website/models/ir_ui_view.py | 3 +++ addons/website/tests/test_views.py | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 4e803e30ff7..f5e2894fe13 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -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) diff --git a/addons/website/tests/test_views.py b/addons/website/tests/test_views.py index 802f1e479b4..8a213921dbd 100644 --- a/addons/website/tests/test_views.py +++ b/addons/website/tests/test_views.py @@ -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):