From 82a91621378ac6fd3dc498dbbe0002a5d5999c2f Mon Sep 17 00:00:00 2001
From: Fabien Meghazi <fme@openerp.com>
Date: Mon, 15 Sep 2014 16:49:39 +0200
Subject: [PATCH] [IMP] avoid 1 query per t-call

---
 addons/website/models/ir_ui_view.py  | 11 ++++++++-
 addons/website/models/website.py     | 20 ++++++----------
 openerp/addons/base/ir/ir_qweb.py    |  8 -------
 openerp/addons/base/ir/ir_ui_view.py | 34 ++++++++++++++++------------
 4 files changed, 37 insertions(+), 36 deletions(-)

diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py
index dbacf0cd9ed8..02dd2f3d351f 100644
--- a/addons/website/models/ir_ui_view.py
+++ b/addons/website/models/ir_ui_view.py
@@ -3,7 +3,7 @@ import copy
 
 from lxml import etree, html
 
-from openerp import SUPERUSER_ID
+from openerp import SUPERUSER_ID, tools
 from openerp.addons.website.models import website
 from openerp.http import request
 from openerp.osv import osv, fields
@@ -139,6 +139,15 @@ class view(osv.osv):
 
         return arch
 
+    @tools.ormcache_context(accepted_keys=('website_id',))
+    def get_view_id(self, cr, uid, xml_id, context=None):
+        if context and 'website_id' in context and not isinstance(xml_id, (int, long)):
+            domain = [('key', '=', xml_id), '|', ('website_id', '=', context['website_id']), ('website_id', '=', False)]
+            [xml_id] = self.search(cr, uid, domain, order='website_id', limit=1, context=context)
+        else:
+            xml_id = super(view, self).get_view_id(cr, uid, xml_id, context=context)
+        return xml_id
+
     def render(self, cr, uid, id_or_xml_id, values=None, engine='ir.qweb', context=None):
         if request and getattr(request, 'website_enabled', False):
             engine='website.qweb'
diff --git a/addons/website/models/website.py b/addons/website/models/website.py
index c801b66b186a..b2d1bb67d6db 100644
--- a/addons/website/models/website.py
+++ b/addons/website/models/website.py
@@ -275,19 +275,13 @@ class website(osv.osv):
         return Access.check(cr, uid, 'ir.ui.menu', 'read', False, context=context)
 
     def get_template(self, cr, uid, ids, template, context=None):
-        if isinstance(template, (int, long)):
-            view_id = template
-
-        else:
-            if '.' not in template:
-                template = 'website.%s' % template
-            module, xmlid = template.split('.', 1)
-            key = template
-            website_id=request.context.get('website_id')
-            view_id=self.pool["ir.ui.view"].search(cr, uid, [('key', '=', key),'|',('website_id','=',website_id),('website_id','=',False)], order='website_id', limit=1, context=context)
-            if not view_id:
-                raise NotFound
-        return self.pool["ir.ui.view"].browse(cr, uid, view_id, context=context)
+        if not isinstance(template, (int, long)) and '.' not in template:
+            template = 'website.%s' % template
+        View = self.pool['ir.ui.view']
+        view_id = View.get_view_id(cr, uid, template, context=context)
+        if not view_id:
+            raise NotFound
+        return View.browse(cr, uid, view_id, context=context)
 
     def _render(self, cr, uid, ids, template, values=None, context=None):
         # TODO: remove this. (just kept for backward api compatibility for saas-3)
diff --git a/openerp/addons/base/ir/ir_qweb.py b/openerp/addons/base/ir/ir_qweb.py
index 74f5bff36f33..5236e04dd841 100644
--- a/openerp/addons/base/ir/ir_qweb.py
+++ b/openerp/addons/base/ir/ir_qweb.py
@@ -237,14 +237,6 @@ class QWeb(orm.AbstractModel):
         if not isinstance(qwebcontext, QWebContext):
             qwebcontext = QWebContext(cr, uid, qwebcontext, loader=loader, context=context)
 
-        if context is None:
-            context = {}
-          
-        website_id=context.get('website_id')
-        if website_id:
-            id_or_xml_id=self.pool["ir.ui.view"].search(cr, uid, [('key', '=', id_or_xml_id),'|',('website_id','=',website_id),('website_id','=',False)], order='website_id', limit=1, context=context)[0]
-
-
         qwebcontext['__template__'] = id_or_xml_id
         stack = qwebcontext.get('__stack__', [])
         if stack:
diff --git a/openerp/addons/base/ir/ir_ui_view.py b/openerp/addons/base/ir/ir_ui_view.py
index 8f1f2e7dafdf..c3ae2b763100 100644
--- a/openerp/addons/base/ir/ir_ui_view.py
+++ b/openerp/addons/base/ir/ir_ui_view.py
@@ -313,7 +313,7 @@ class view(osv.osv):
         if not values.get('name'):
             values['name'] = "%s %s" % (values.get('model'), values['type'])
 
-        self.read_template.clear_cache(self)
+        self._read_template.clear_cache(self)
         return super(view, self).create(
             cr, uid,
             self._compute_defaults(cr, uid, values, context=context),
@@ -336,7 +336,7 @@ class view(osv.osv):
         if custom_view_ids:
             self.pool.get('ir.ui.view.custom').unlink(cr, uid, custom_view_ids)
 
-        self.read_template.clear_cache(self)
+        self._read_template.clear_cache(self)
         ret = super(view, self).write(
             cr, uid, ids,
             self._compute_defaults(cr, uid, vals, context=context),
@@ -897,18 +897,11 @@ class view(osv.osv):
     #------------------------------------------------------
     # QWeb template views
     #------------------------------------------------------
-    read_template_cache = dict(accepted_keys=('lang','inherit_branding', 'editable', 'translatable'))
+    _read_template_cache = dict(accepted_keys=('lang','inherit_branding', 'editable', 'translatable'))
     if config['dev_mode']:
-        read_template_cache['size'] = 0
-    @tools.ormcache_context(**read_template_cache)
-    def read_template(self, cr, uid, xml_id, context=None):
-        if isinstance(xml_id, (int, long)):
-            view_id = xml_id
-        else:
-            if '.' not in xml_id:
-                raise ValueError('Invalid template id: %r' % (xml_id,))
-            view_id = self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
-
+        _read_template_cache['size'] = 0
+    @tools.ormcache_context(**_read_template_cache)
+    def _read_template(self, cr, uid, view_id, context=None):
         arch = self.read_combined(cr, uid, view_id, fields=['arch'], context=context)['arch']
         arch_tree = etree.fromstring(arch)
 
@@ -921,8 +914,21 @@ class view(osv.osv):
         arch = etree.tostring(root, encoding='utf-8', xml_declaration=True)
         return arch
 
+    def read_template(self, cr, uid, xml_id, context=None):
+        if isinstance(xml_id, (int, long)):
+            view_id = xml_id
+        else:
+            if '.' not in xml_id:
+                raise ValueError('Invalid template id: %r' % (xml_id,))
+            view_id = self.get_view_id(cr, uid, xml_id, context=context)
+        return self._read_template(cr, uid, view_id, context=context)
+
+    @tools.ormcache(skiparg=3)
+    def get_view_id(self, cr, uid, xml_id, context=None):
+        return self.pool['ir.model.data'].xmlid_to_res_id(cr, uid, xml_id, raise_if_not_found=True)
+
     def clear_cache(self):
-        self.read_template.clear_cache(self)
+        self._read_template.clear_cache(self)
 
     def _contains_branded(self, node):
         return node.tag == 't'\
-- 
GitLab