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
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)
: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
import test_ir_values
import test_menu
import test_search
+import test_views
checks = [
test_base,
test_ir_values,
test_menu,
test_search,
+ test_views,
]
--- /dev/null
+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()
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)