[FIX] ir.ui.view: properly validate newly created inheriting views
When a new inheriting view is imported during a module installation, it is validated thanks to the _constraints on the ir.ui.view model. However the validation uses a rather convoluted system for validating the whole view tree at once (root view + all inherited changes) while only taking into account the views that belong to modules that are currently loaded. This complicated system is necessary to be able to operate on-the-fly at any point during the registry loading/initialization. Now because _constraints are checked during create() this particular validation happens *before* the external ID (ir.model.data entry) of that new view can be created (it obviously needs to wait until the view record is inserted). As a consequence the view validation cannot determine the module to which that new view belongs, and was erroneously ignoring it. Changing the view filtering to also include views that have triggered this check. Manually created views are not check during registry update. bzr revid: chs@openerp.com-20130912141018-qmcyase8zqov9d01
This commit is contained in:
parent
b17fd217bd
commit
1d91378ce2
|
@ -125,11 +125,15 @@ class view(osv.osv):
|
|||
try:
|
||||
fvg = self.pool.get(view.model).fields_view_get(cr, uid, view_id=view.id, view_type=view.type, context=context)
|
||||
return fvg['arch']
|
||||
except:
|
||||
except Exception:
|
||||
_logger.exception("Can't render view %s for model: %s", view.xml_id, view.model)
|
||||
return False
|
||||
|
||||
def _check_xml(self, cr, uid, ids, context=None):
|
||||
if context is None:
|
||||
context = {}
|
||||
context['check_view_ids'] = ids
|
||||
|
||||
for view in self.browse(cr, uid, ids, context):
|
||||
# Sanity check: the view should not break anything upon rendering!
|
||||
view_arch_utf8 = self._check_render_view(cr, uid, view, context=context)
|
||||
|
@ -175,13 +179,15 @@ class view(osv.osv):
|
|||
:rtype: list of tuples
|
||||
:return: [(view_arch,view_id), ...]
|
||||
"""
|
||||
|
||||
user_groups = frozenset(self.pool.get('res.users').browse(cr, 1, uid, context).groups_id)
|
||||
if self.pool._init:
|
||||
# Module init currently in progress, only consider views from modules whose code was already loaded
|
||||
check_view_ids = context and context.get('check_view_ids') or (0,)
|
||||
query = """SELECT v.id FROM ir_ui_view v LEFT JOIN ir_model_data md ON (md.model = 'ir.ui.view' AND md.res_id = v.id)
|
||||
WHERE v.inherit_id=%s AND v.model=%s AND (md.module IS NULL or md.module in %s)
|
||||
WHERE v.inherit_id=%s AND v.model=%s AND (md.module in %s OR v.id in %s)
|
||||
ORDER BY priority"""
|
||||
query_params = (view_id, model, tuple(self.pool._init_modules))
|
||||
query_params = (view_id, model, tuple(self.pool._init_modules), tuple(check_view_ids))
|
||||
else:
|
||||
# Modules fully loaded, consider all views
|
||||
query = """SELECT v.id FROM ir_ui_view v
|
||||
|
|
|
@ -4,6 +4,7 @@ import test_ir_attachment
|
|||
import test_ir_values
|
||||
import test_menu
|
||||
import test_search
|
||||
import test_views
|
||||
|
||||
checks = [
|
||||
test_base,
|
||||
|
@ -12,4 +13,5 @@ checks = [
|
|||
test_ir_values,
|
||||
test_menu,
|
||||
test_search,
|
||||
test_views,
|
||||
]
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
import unittest2
|
||||
|
||||
import openerp.tests.common as common
|
||||
from openerp.osv.orm import except_orm
|
||||
from openerp.tools import mute_logger
|
||||
|
||||
class test_views(common.TransactionCase):
|
||||
|
||||
@mute_logger('openerp.osv.orm', 'openerp.addons.base.ir.ir_ui_view')
|
||||
def test_00_init_check_views(self):
|
||||
Views = self.registry('ir.ui.view')
|
||||
|
||||
self.assertTrue(Views.pool._init)
|
||||
|
||||
error_msg = "Invalid XML for View Architecture"
|
||||
# test arch check is call for views without xmlid during registry initialization
|
||||
with self.assertRaisesRegexp(except_orm, error_msg):
|
||||
Views.create(self.cr, self.uid, {
|
||||
'name': 'Test View #1',
|
||||
'model': 'ir.ui.view',
|
||||
'arch': """<?xml version="1.0"?>
|
||||
<tree>
|
||||
<field name="test_1"/>
|
||||
</tree>
|
||||
""",
|
||||
})
|
||||
|
||||
# same for inherited views
|
||||
with self.assertRaisesRegexp(except_orm, error_msg):
|
||||
# Views.pudb = True
|
||||
Views.create(self.cr, self.uid, {
|
||||
'name': 'Test View #2',
|
||||
'model': 'ir.ui.view',
|
||||
'inherit_id': self.browse_ref('base.view_view_tree').id,
|
||||
'arch': """<?xml version="1.0"?>
|
||||
<xpath expr="//field[@name='name']" position="after">
|
||||
<field name="test_2"/>
|
||||
</xpath>
|
||||
""",
|
||||
})
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest2.main()
|
|
@ -2190,7 +2190,7 @@ class BaseModel(object):
|
|||
are applied
|
||||
|
||||
"""
|
||||
sql_inherit = self.pool.get('ir.ui.view').get_inheriting_views_arch(cr, user, inherit_id, self._name)
|
||||
sql_inherit = self.pool.get('ir.ui.view').get_inheriting_views_arch(cr, user, inherit_id, self._name, context=context)
|
||||
for (view_arch, view_id) in sql_inherit:
|
||||
source = apply_inheritance_specs(source, view_arch, view_id)
|
||||
source = apply_view_inheritance(cr, user, source, view_id)
|
||||
|
|
Loading…
Reference in New Issue