diff --git a/addons/web_editor/models/ir_ui_view.py b/addons/web_editor/models/ir_ui_view.py index 908f58e6b8c..bb38e2d0652 100644 --- a/addons/web_editor/models/ir_ui_view.py +++ b/addons/web_editor/models/ir_ui_view.py @@ -199,6 +199,14 @@ class IrUiView(models.Model): self.sudo().model_data_id.write({'noupdate': True}) # TODO check if we remove this self.write({'arch': self._pretty_arch(new_arch)}) + @api.model + def _view_get_inherited_children(self, view, options): + extensions = view.inherit_children_ids + if not options: + # only active children + extensions = extensions.filtered(lambda view: view.active) + return extensions + @api.model def _view_obj(self, view_id): if isinstance(view_id, pycompat.string_types): @@ -244,10 +252,7 @@ class IrUiView(models.Model): if called_view and called_view not in views_to_return: views_to_return += self._views_get(called_view, options=options, bundles=bundles) - extensions = view.inherit_children_ids - if not options: - # only active children - extensions = view.inherit_children_ids.filtered(lambda view: view.active) + extensions = self._view_get_inherited_children(view, options) # Keep options in a deterministic order regardless of their applicability for extension in extensions.sorted(key=lambda v: v.id): diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index bead9cbb5ee..5a4c4611ff2 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -130,20 +130,7 @@ class View(models.Model): # method should never be called in a generic context, even for # tests) self = self.with_context(website_id=self.env['website'].get_current_website().id) - views = super(View, self).get_related_views(key, bundles=bundles) - current_website_id = self._context.get('website_id') - most_specific_views = self.env['ir.ui.view'] - - if not current_website_id: - return views - - for view in views: - if view.website_id and view.website_id.id == current_website_id: - most_specific_views |= view - 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 views): - most_specific_views |= view - - return most_specific_views + return super(View, self).get_related_views(key, bundles=bundles) @api.multi def _sort_suitability_key(self): @@ -167,6 +154,11 @@ class View(models.Model): filtered += sorted(group, key=lambda record: record._sort_suitability_key())[0] return (filtered + view_without_key).sorted(key=lambda view: (view.priority, view.id)) + @api.model + def _view_get_inherited_children(self, view, options): + extensions = super(View, self)._view_get_inherited_children(view, options) + return extensions.filter_duplicate() + @api.model def _view_obj(self, view_id): ''' Given an xml_id or a view_id, return the corresponding view record. diff --git a/addons/website/tests/test_views.py b/addons/website/tests/test_views.py index 99fc814a271..0f4dcb1a91e 100644 --- a/addons/website/tests/test_views.py +++ b/addons/website/tests/test_views.py @@ -590,3 +590,34 @@ class TestCowViewSaving(common.TransactionCase): self.assertEqual(view.active, True, "filter_duplicate should return the generic one") view = View.with_context(active_test=False, website_id=1).search([('key', '=', self.inherit_view.key)]).filter_duplicate() self.assertEqual(view.active, False, "filter_duplicate should return the specific one") + + def test_get_related_views_tree(self): + View = self.env['ir.ui.view'] + + self.base_view.write({'name': 'B', 'key': 'B'}) + self.inherit_view.write({'name': 'I', 'key': 'I'}) + View.create({ + 'name': 'II', + 'mode': 'extension', + 'inherit_id': self.inherit_view.id, + 'arch': '