[FIX] base,*: add MODULE_UNINSTALL_FLAG to cleanup views

* website_theme_install

This commit will add MODULE_UNINSTALL_FLAG to the cleanup methods of themes and
modules.

This is necessary to also unlink inherited views of those we try to unlink.

Before this commit, an error would be raised when trying to delete a view that
still had other inherited views (either created manually by the user, or with
just bad luck in the order of which the views are deleted).

PR: #29753
This commit is contained in:
Sébastien Theys
2019-01-09 12:54:47 +00:00
parent 2e32cc5aa3
commit c4ee25fb7f
3 changed files with 25 additions and 4 deletions
@@ -18,6 +18,18 @@ class TestWebsiteSaleComparison(odoo.tests.TransactionCase):
Website0 = self.env['website'].with_context(website_id=None)
Website1 = self.env['website'].with_context(website_id=1)
# Create a generic inherited view, with a key not starting with
# `website_sale_comparison` otherwise the unlink will work just based on
# the key, but we want to test also for `MODULE_UNINSTALL_FLAG`.
product_add_to_compare = Website0.viewref('website_sale_comparison.product_add_to_compare')
test_view_key = 'my_test.my_key'
self.env['ir.ui.view'].with_context(website_id=None).create({
'name': 'test inherited view',
'key': test_view_key,
'inherit_id': product_add_to_compare.id,
'arch': '<div/>',
})
# Retrieve the generic view
product = Website0.viewref('website_sale.product')
# Trigger COW to create specific views of the whole tree
@@ -26,6 +38,7 @@ class TestWebsiteSaleComparison(odoo.tests.TransactionCase):
# Verify initial state: the specific views exist
self.assertEquals(Website1.viewref('website_sale.product').website_id.id, 1)
self.assertEquals(Website1.viewref('website_sale_comparison.product_add_to_compare').website_id.id, 1)
self.assertEquals(Website1.viewref(test_view_key).website_id.id, 1)
# Remove the module (use `module_uninstall` because it is enough to test
# what we want here, no need/can't use `button_immediate_uninstall`
@@ -37,3 +50,8 @@ class TestWebsiteSaleComparison(odoo.tests.TransactionCase):
self.assertFalse(Website0.viewref('website_sale_comparison.product_add_to_compare', raise_if_not_found=False))
# Check that the specific view is correctly removed
self.assertFalse(Website1.viewref('website_sale_comparison.product_add_to_compare', raise_if_not_found=False))
# Check that the generic inherited view is correctly removed
self.assertFalse(Website0.viewref(test_view_key, raise_if_not_found=False))
# Check that the specific inherited view is correctly removed
self.assertFalse(Website1.viewref(test_view_key, raise_if_not_found=False))
@@ -6,6 +6,7 @@ import os
from collections import OrderedDict
from odoo import api, fields, models
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
from odoo.exceptions import MissingError
from odoo.http import request
@@ -206,7 +207,7 @@ class IrModuleModule(models.Model):
for model_name in self._theme_model_names:
template = self._get_module_data(model_name)
models = template.with_context(active_test=False).mapped('copy_ids').filtered(lambda m: m.website_id == website)
models = template.with_context(**{'active_test': False, MODULE_UNINSTALL_FLAG: True}).mapped('copy_ids').filtered(lambda m: m.website_id == website)
models.unlink()
self._theme_cleanup(model_name, website)
@@ -235,8 +236,9 @@ class IrModuleModule(models.Model):
if model_name in ('website.page', 'website.menu'):
return model
orphans = model.with_context(active_test=False).search([
# use active_test to also unlink archived models
# and use MODULE_UNINSTALL_FLAG to also unlink inherited models
orphans = model.with_context(**{'active_test': False, MODULE_UNINSTALL_FLAG: True}).search([
('key', '=like', self.name + '.%'),
('website_id', '=', website.id),
('theme_template_id', '=', False),
+2 -1
View File
@@ -24,6 +24,7 @@ import lxml.html
import odoo
from odoo import api, fields, models, modules, tools, _
from odoo.addons.base.models.ir_model import MODULE_UNINSTALL_FLAG
from odoo.exceptions import AccessDenied, UserError
from odoo.osv import expression
from odoo.tools.parse_version import parse_version
@@ -472,7 +473,7 @@ class Module(models.Model):
they rely on data that don't exist anymore if the module is removed.
"""
domain = expression.OR([[('key', '=like', m.name + '.%')] for m in self])
orphans = self.env['ir.ui.view'].with_context(active_test=False).search(domain)
orphans = self.env['ir.ui.view'].with_context(**{'active_test': False, MODULE_UNINSTALL_FLAG: True}).search(domain)
orphans.unlink()
@api.multi