[FIX] website{,_version}: get current version view

customize_template_get which gets template inheritence informations was
not taken into account by website version, so at one time we could get
an erroneous view version instead of the wanted one.

This commit refactor some of the code adding a function to sort view and
find the most suitable one (based on website and version in request).

This function is then used in ir.ui.view `_view_obj`'s function to
select the correct view.

related to opw-667225
This commit is contained in:
Nicolas Lempereur
2016-03-08 17:13:58 +01:00
parent f0257a9c72
commit b0b6b9afb5
2 changed files with 47 additions and 36 deletions
+25 -1
View File
@@ -2,6 +2,7 @@
import copy
import logging
from itertools import groupby
from lxml import etree, html
from openerp import SUPERUSER_ID, api, tools
@@ -33,6 +34,29 @@ class view(osv.osv):
self.clear_caches()
return res
def _sort_suitability_key(self):
"""
Key function to sort views by descending suitability
Suitability of a view is defined as follow:
* if the view and request website_id are matched
* then if the view has no set website
"""
context_website_id = self.env.context.get('website_id', 1)
website_id = self.website_id.id or 0
different_website = context_website_id != website_id
return (different_website, website_id)
def filter_duplicate(self):
"""
Filter current recordset only keeping the most suitable view per distinct key
"""
filtered = self.browse([])
for _, group in groupby(self, key=lambda r:r.key):
filtered += sorted(group, key=lambda r:r._sort_suitability_key())[0]
return filtered
def _view_obj(self, cr, uid, view_id, context=None):
if isinstance(view_id, basestring):
if 'website_id' in context:
@@ -41,7 +65,7 @@ class view(osv.osv):
else:
rec_id = self.search(cr, uid, [('key', '=', view_id)], context=context)
if rec_id:
return self.browse(cr, uid, rec_id, context=context)[0]
return self.browse(cr, uid, rec_id, context=context).filter_duplicate()
else:
return self.pool['ir.model.data'].xmlid_to_object(
cr, uid, view_id, raise_if_not_found=True, context=context)
+22 -35
View File
@@ -9,6 +9,22 @@ class view(models.Model):
version_id = fields.Many2one('website_version.version', ondelete='cascade', string="Version")
def _sort_suitability_key(self):
"""
Key function to sort views by descending suitability
Suitability of a view is defined as follow:
* if the view and request version are matched,
* then fallback on previously defined suitability
"""
original_suitability = super(view, self)._sort_suitability_key()
context_version_id = self.env.context.get('version_id', 0)
different_version = context_version_id != (self.version_id.id or 0)
return (different_version, original_suitability)
@api.multi
def write(self, vals):
if self.env.context is None:
@@ -83,41 +99,12 @@ class view(models.Model):
vw = self.browse(view_id)
if not (self.env.context and self.env.context.get('website_id') and vw.type == 'qweb'):
return arch
#right_ids to collect the right ids according to the key
right_ids = {}
priority = {}
#To create a dico called view_arch where v(key) is the id and a the arch(value)
view_arch = dict([(v, a) for a, v in arch])
keys = self.browse(view_arch.keys())
#The view to take depends of the context
context_version_id = self.env.context.get('version_id')
context_website_id = self.env.context.get('website_id')
for k in keys:
#priority:1(with context_version_id) take the view which is in the same version
if context_version_id and k.version_id.id and k.version_id.id == context_version_id:
right_ids[k.key] = k.id
priority[k.key] = 3
#priority:2(context_version_id) take the view which is just in the same website
elif context_version_id and k.version_id.id is False and k.website_id.id and k.website_id.id == context_website_id:
if not priority.get(k.key) or priority.get(k.key) < 3:
right_ids[k.key] = k.id
priority[k.key] = 2
#priority:3(context_version_id) take the original view
elif context_version_id and k.version_id.id is False and k.website_id.id is False:
if not priority.get(k.key) or priority.get(k.key) < 2:
right_ids[k.key] = k.id
priority[k.key] = 1
#priority:1(without context_version_id) take the view which is just in the same website
elif not context_version_id and k.version_id.id is False and k.website_id.id and k.website_id.id == context_website_id:
right_ids[k.key] = k.id
priority[k.key] = 2
#priority:2(without context_version_id) take the original view
elif not context_version_id and k.version_id.id is False and k.website_id.id is False:
if not priority.get(k.key) or priority.get(k.key) < 2:
right_ids[k.key] = k.id
priority[k.key] = 1
return [x for x in arch if x[1] in right_ids.values()]
# keep the most suited view when several view with same key are available
chosen_view_ids = self.browse(view_id for _, view_id in arch).filter_duplicate().ids
return [x for x in arch if x[1] in chosen_view_ids]
#To active or desactive the right views according to the key
def toggle(self, cr, uid, ids, context=None):
""" Switches between enabled and disabled statuses