diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index e2823754069..86c6e82365e 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -144,8 +144,12 @@ class View(models.Model): return self.filtered(lambda view: not view.website_id) for view in self: + # specific view: add it if it's for the current website and ignore + # it if it's for another website if view.website_id and view.website_id.id == current_website_id: most_specific_views |= view + # generic view: add it only if, for the current website, there is no + # specific view for this view (based on the same `key` attribute) elif not view.website_id and not any(view.key == view2.key and view2.website_id and view2.website_id.id == current_website_id for view2 in self): most_specific_views |= view @@ -202,6 +206,17 @@ class View(models.Model): @api.model @tools.ormcache_context('self._uid', 'xml_id', keys=('website_id',)) def get_view_id(self, xml_id): + """If a website_id is in the context and the given xml_id is not an int + then try to get the id of the specific view for that website, but + fallback to the id of the generic view if there is no specific. + + If no website_id is in the context, it might randomly return the generic + or the specific view, so it's probably not recommanded to use this + method. `viewref` is probably more suitable. + + Archived views are ignored (unless the active_test context is set, but + then the ormcache_context will not work as expected). + """ if 'website_id' in self._context and not isinstance(xml_id, pycompat.integer_types): current_website = self.env['website'].browse(self._context.get('website_id')) domain = ['&', ('key', '=', xml_id)] + current_website.website_domain() diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 16b6a597969..9a714a1e6e6 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -504,6 +504,12 @@ class Website(models.Model): def viewref(self, view_id, raise_if_not_found=True): ''' Given an xml_id or a view_id, return the corresponding view record. In case of website context, return the most specific one. + + If no website_id is in the context, it will return the generic view, + instead of a random one like `get_view_id`. + + Look also for archived views, no matter the context. + :param view_id: either a string xml_id or an integer view_id :param raise_if_not_found: should the method raise an error if no view found :return: The view record or empty recordset diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index c46b9ba87d2..802711f5f5c 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -1174,6 +1174,9 @@ actual arch. """ Return the view ID corresponding to ``template``, which may be a view ID or an XML ID. Note that this method may be overridden for other kinds of template values. + + This method could return the ID of something that is not a view (when + using fallback to `xmlid_to_res_id`). """ if isinstance(template, pycompat.integer_types): return template