diff --git a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js index 29a91574786..7e3da3e3c9e 100644 --- a/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js +++ b/addons/hr_holidays/static/src/js/time_off_calendar/time_off_calendar_controller.js @@ -131,15 +131,8 @@ export const TimeOffCalendarController = CalendarController.extend({ * @private */ async _onNewTimeOff() { - const viewId = await this._rpc({ - model: 'ir.ui.view', - method: 'get_view_id', - args: ['hr_holidays.hr_leave_view_form_dashboard_new_time_off'], - }); - this.timeOffDialog = new dialogs.FormViewDialog(this, { res_model: "hr.leave", - view_id: viewId, context: this._getTimeOffContext(), title: _t("New time off"), disable_multiple_selection: true, @@ -154,17 +147,8 @@ export const TimeOffCalendarController = CalendarController.extend({ * @private */ async _onNewAllocation() { - const viewXmlId = this._getFormViewId(); - - const viewId = await this._rpc({ - model: 'ir.ui.view', - method: 'get_view_id', - args: [viewXmlId], - }); - this.allocationDialog = new dialogs.FormViewDialog(this, { res_model: "hr.leave.allocation", - view_id: viewId, context: this._getAllocationContext(), title: _t("New Allocation"), disable_multiple_selection: true, @@ -203,6 +187,7 @@ export const TimeOffCalendarController = CalendarController.extend({ 'default_date_from': moment().locale('en').format('YYYY-MM-DD'), 'default_date_to': moment().add(1, 'days').locale('en').format('YYYY-MM-DD'), 'lang': this.context.lang, + 'form_view_ref': 'hr_holidays.hr_leave_view_form_dashboard_new_time_off' }; }, @@ -210,6 +195,7 @@ export const TimeOffCalendarController = CalendarController.extend({ return { 'default_state': 'confirm', 'lang': this.context.lang, + 'form_view_ref': this._getFormViewId() }; }, diff --git a/addons/test_website/tests/test_reset_views.py b/addons/test_website/tests/test_reset_views.py index 2c22471cc5d..2d8bf7fe656 100644 --- a/addons/test_website/tests/test_reset_views.py +++ b/addons/test_website/tests/test_reset_views.py @@ -79,7 +79,7 @@ class TestWebsiteResetViews(odoo.tests.HttpCase): # self.assertEqual(total_views + 1, self.View.search_count([('type', '=', 'qweb')]), "Missing COW view (1)") # self.fix_it('/test_view') - # also mute ir.ui.view as `get_view_id()` will raise "Could not find view object with xml_id 'no_record.exist'"" + # also mute ir.ui.view as `_get_view_id()` will raise "Could not find view object with xml_id 'no_record.exist'"" @mute_logger('odoo.http', 'odoo.addons.website.models.ir_ui_view') def test_06_reset_specific_view_controller_inexisting_template(self): total_views = self.View.search_count([('type', '=', 'qweb')]) diff --git a/addons/web_editor/models/ir_qweb_fields.py b/addons/web_editor/models/ir_qweb_fields.py index 4b6f3433a0d..43766b2f690 100644 --- a/addons/web_editor/models/ir_qweb_fields.py +++ b/addons/web_editor/models/ir_qweb_fields.py @@ -75,14 +75,13 @@ class IrQWeb(models.AbstractModel): key = el.attrib.pop('t-snippet') el.set('t-call', key) el.set('t-options', f"{{'snippet-key': {key!r}}}") - View = self.env['ir.ui.view'].sudo() - view_id = View.get_view_id(key) - name = View.browse(view_id).name + view = self.env['ir.ui.view']._get_view(key).sudo() + name = view.name thumbnail = el.attrib.pop('t-thumbnail', "oe-thumbnail") div = '
' % ( escape(pycompat.to_text(name)), escape(pycompat.to_text(thumbnail)), - escape(pycompat.to_text(view_id)), + escape(pycompat.to_text(view.id)), escape(pycompat.to_text(el.findtext('keywords'))) ) self._append_text(div, options) diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 5df5b94ae59..00d61296f64 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -349,7 +349,7 @@ class View(models.Model): @api.model @tools.ormcache_context('self.env.uid', 'self.env.su', 'xml_id', keys=('website_id',)) - def get_view_id(self, xml_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. @@ -370,7 +370,7 @@ class View(models.Model): _logger.warning("Could not find view object with xml_id '%s'", xml_id) raise ValueError('View %r in website %r not found' % (xml_id, self._context['website_id'])) return view.id - return super(View, self.sudo()).get_view_id(xml_id) + return super(View, self.sudo())._get_view_id(xml_id) def _handle_visibility(self, do_raise=True): """ Check the visibility set on the main view and raise 403 if you should not have access. @@ -409,7 +409,7 @@ class View(models.Model): def _render_template(self, template, values=None): """ Render the template. If website is enabled on request, then extend rendering context with website values. """ - view = self.sudo().browse(self.get_view_id(template)) + view = self._get_view(template).sudo() view._handle_visibility(do_raise=True) if values is None: values = {} diff --git a/addons/website/models/website.py b/addons/website/models/website.py index 6a4af434d15..6df04219989 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -1033,7 +1033,7 @@ class Website(models.Model): 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`. + instead of a random one like `_get_view_id`. Look also for archived views, no matter the context. @@ -1088,16 +1088,12 @@ class Website(models.Model): @api.model def get_template(self, template): - View = self.env['ir.ui.view'] - if isinstance(template, int): - view_id = template - else: - if '.' not in template: - template = 'website.%s' % template - view_id = View.get_view_id(template) - if not view_id: + if isinstance(template, str) and '.' not in template: + template = 'website.%s' % template + view = self.env['ir.ui.view']._get_view(template).sudo() + if not view: raise NotFound - return View.sudo().browse(view_id) + return view @api.model def pager(self, url, total, page=1, step=30, scope=5, url_args=None): diff --git a/addons/website/tests/test_views.py b/addons/website/tests/test_views.py index 49ffb93c698..728d62a82da 100644 --- a/addons/website/tests/test_views.py +++ b/addons/website/tests/test_views.py @@ -582,8 +582,8 @@ class TestCowViewSaving(TestViewSavingCommon): main_view.with_context(website_id=1).write({'arch': 'SPECIFIC
Z
'}) self.assertEqual(total_views + 3 + 3, View.search_count([]), "It should have duplicated the Main View tree as a specific tree and then removed the specific view from the generic tree as no more needed") - generic_view = View.with_context(website_id=None).get_view_id('website.main_view') - specific_view = View.with_context(website_id=1).get_view_id('website.main_view') + generic_view = View.with_context(website_id=None)._get_view_id('website.main_view') + specific_view = View.with_context(website_id=1)._get_view_id('website.main_view') generic_view_arch = View.browse(generic_view).with_context(load_all_views=True).get_combined_arch() specific_view_arch = View.browse(specific_view).with_context(load_all_views=True, website_id=1).get_combined_arch() self.assertEqual(generic_view_arch, 'GENERIC
VIEWC
') diff --git a/odoo/addons/base/models/ir_qweb.py b/odoo/addons/base/models/ir_qweb.py index be9d4264704..309666cdc52 100644 --- a/odoo/addons/base/models/ir_qweb.py +++ b/odoo/addons/base/models/ir_qweb.py @@ -740,10 +740,9 @@ class IrQWeb(models.AbstractModel): identifier :rtype: Tuple[Union[etree, str], Optional[str, int]] """ - IrUIView = self.env['ir.ui.view'] - view_id = IrUIView.get_view_id(ref) - view = IrUIView.sudo().browse(view_id) - template = IrUIView.sudo()._read_template(view_id) + IrUIView = self.env['ir.ui.view'].sudo() + view = IrUIView._get_view(ref) + template = IrUIView._read_template(view.id) etree_view = etree.fromstring(template) xmlid = view.key or ref @@ -765,7 +764,7 @@ class IrQWeb(models.AbstractModel): etree_view = node break etree_view.set('t-name', str(xmlid)) - return (etree_view, view_id) + return (etree_view, view.id) # values for running time diff --git a/odoo/addons/base/models/ir_ui_view.py b/odoo/addons/base/models/ir_ui_view.py index 4d8bdf28803..f414c57550a 100644 --- a/odoo/addons/base/models/ir_ui_view.py +++ b/odoo/addons/base/models/ir_ui_view.py @@ -1824,20 +1824,28 @@ actual arch. return etree.tostring(arch_tree, encoding='unicode') @api.model - def get_view_id(self, template): + def _get_view_id(self, template): """ 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, int): return template if '.' not in template: raise ValueError('Invalid template id: %r' % template) view = self.sudo().search([('key', '=', template)], limit=1) - return view and view.id or self.env['ir.model.data']._xmlid_to_res_id(template, raise_if_not_found=True) + if view: + return view.id + res_model, res_id = self.env['ir.model.data']._xmlid_to_res_model_res_id(template, raise_if_not_found=True) + assert res_model == self._name, "Call _get_view_id, expected %r, got %r" % (self._name, res_model) + return res_id + + @api.model + def _get_view(self, view_ref): + """ Return the view corresponding to ``view_ref``, which may be a + view ID or an XML ID. + """ + return self.browse(self._get_view_id(view_ref)) def clear_cache(self): """ Deprecated, use `clear_caches` instead. """ @@ -1927,8 +1935,8 @@ actual arch. @api.model def render_public_asset(self, template, values=None): - template = self.sudo().browse(self.get_view_id(template)) - template._check_view_access() + template_sudo = self._get_view(template).sudo() + template_sudo._check_view_access() return self.env['ir.qweb'].sudo()._render(template, values) def _render_template(self, template, values=None):