[MERGE] forward port branch saas-12 up to b1b700a

This commit is contained in:
Christophe Simonis
2016-09-22 15:23:45 +02:00
32 changed files with 1030 additions and 972 deletions
+1 -1
View File
@@ -8826,7 +8826,7 @@ msgstr ""
#. module: base
#: code:addons/base/res/res_users.py:316
#, python-format
msgid "Invalid group by"
msgid "Invalid 'group by' parameter"
msgstr ""
#. module: base
+8 -3
View File
@@ -414,6 +414,7 @@ class IrModelFields(models.Model):
any(field.state != 'manual' for field in self):
raise UserError(_("This column contains module data and cannot be removed!"))
model_names = self.mapped('model')
self._drop_column()
res = super(IrModelFields, self).unlink()
@@ -423,6 +424,8 @@ class IrModelFields(models.Model):
self._cr.commit()
api.Environment.reset()
registry = Registry.new(self._cr.dbname)
models = registry.descendants(model_names, '_inherits')
registry.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
registry.signal_registry_change()
return res
@@ -455,8 +458,9 @@ class IrModelFields(models.Model):
if vals['model'] in self.pool:
# setup models; this re-initializes model in registry
self.pool.setup_models(self._cr, partial=(not self.pool.ready))
# update database schema
self.pool.init_models(self._cr, [vals['model']], dict(self._context, update_custom_fields=True))
# update database schema of model and its descendant models
models = self.pool.descendants([vals['model']], '_inherits')
self.pool.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
self.pool.signal_registry_change()
return res
@@ -538,7 +542,8 @@ class IrModelFields(models.Model):
if patched_models:
# update the database schema of the models to patch
self.pool.init_models(self._cr, patched_models, dict(self._context, update_custom_fields=True))
models = self.pool.descendants(patched_models, '_inherits')
self.pool.init_models(self._cr, models, dict(self._context, update_custom_fields=True))
if column_rename or patched_models:
self.pool.signal_registry_change()
+1 -1
View File
@@ -246,7 +246,7 @@ class QWeb(object):
"""
body = []
self.compile(template, options)(self, body.append, values or {})
return u''.join(body)
return u''.join(body).encode('utf8')
def compile(self, template, options):
""" Compile the given template into a rendering function::
+1 -1
View File
@@ -313,7 +313,7 @@ class Users(models.Model):
if self._uid != SUPERUSER_ID:
groupby_fields = set([groupby] if isinstance(groupby, basestring) else groupby)
if groupby_fields.intersection(USER_PRIVATE_FIELDS):
raise AccessError(_('Invalid group by'))
raise AccessError(_("Invalid 'group by' parameter"))
return super(Users, self).read_group(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
@api.model
+5 -5
View File
@@ -25,7 +25,7 @@ class TestQWebTField(TransactionCase):
field = etree.Element('span', {'t-field': u'company.name'})
company = self.env['res.company'].create({'name': "My Test Company"})
result = self.engine.render(field, {'company': company}).encode('utf-8')
result = self.engine.render(field, {'company': company})
self.assertEqual(
result,
'<span data-oe-model="res.company" data-oe-id="%d" '
@@ -41,7 +41,7 @@ class TestQWebTField(TransactionCase):
s = u"Testing «ταБЬℓσ»: 1<2 & 4+1>3, now 20% off!"
company = self.env['res.company'].create({'name': s})
result = self.engine.render(field, {'company': company}).encode('utf-8')
result = self.engine.render(field, {'company': company})
self.assertEqual(
result,
'<span data-oe-model="res.company" data-oe-id="%d" '
@@ -56,13 +56,13 @@ class TestQWebTField(TransactionCase):
field = etree.Element('td', {'t-field': u'company.name'})
with self.assertRaisesRegexp(QWebException, r'^RTE widgets do not work correctly'):
self.engine.render(field, {'company': None}).encode('utf-8')
self.engine.render(field, {'company': None})
def test_reject_t_tag(self):
field = etree.Element('t', {'t-field': u'company.name'})
with self.assertRaisesRegexp(QWebException, r'^t-field can not be used on a t element'):
self.engine.render(field, {'company': None}).encode('utf-8')
self.engine.render(field, {'company': None})
from copy import deepcopy
@@ -128,7 +128,7 @@ class TestQWeb(TransactionCase):
result = doc.find('result[@id="{}"]'.format(template)).text
self.assertEqual(
qweb.render(template, values=params, load=loader).strip().encode('utf-8'),
qweb.render(template, values=params, load=loader).strip(),
(result or u'').strip().encode('utf-8'),
template
)
+9 -3
View File
@@ -377,6 +377,7 @@ class BaseModel(object):
cr.execute(query, vals)
self.invalidate_cache()
@api.model
def _add_field(self, name, field):
""" Add the given ``field`` under the given ``name`` in the class """
@@ -536,6 +537,7 @@ class BaseModel(object):
'_register': False,
'_original_module': cls._module,
'_inherit_children': OrderedSet(), # names of children models
'_inherits_children': set(), # names of children models
'_fields': {}, # populated in _setup_base()
})
check_parent = cls._build_model_check_parent
@@ -633,7 +635,11 @@ class BaseModel(object):
cls._sequence = cls._sequence or (cls._table + '_id_seq')
cls._constraints = cls._constraints.values()
# recompute attributes of children models
# update _inherits_children of parent models
for parent_name in cls._inherits:
pool[parent_name]._inherits_children.add(cls._name)
# recompute attributes of _inherit_children models
for child_name in cls._inherit_children:
child_class = pool[child_name]
child_class._build_model_attributes(pool)
@@ -1933,7 +1939,7 @@ class BaseModel(object):
"""
result = self._read_group_raw(domain, fields, groupby, offset=offset, limit=limit, orderby=orderby, lazy=lazy)
groupby = [groupby] if isinstance(groupby, basestring) else groupby
groupby = [groupby] if isinstance(groupby, basestring) else list(OrderedSet(groupby))
dt = [
f for f in groupby
if self._fields[f.split(':')[0]].type in ('date', 'datetime')
@@ -1957,7 +1963,7 @@ class BaseModel(object):
query = self._where_calc(domain)
fields = fields or [f.name for f in self._fields.itervalues() if f.store]
groupby = [groupby] if isinstance(groupby, basestring) else groupby
groupby = [groupby] if isinstance(groupby, basestring) else list(OrderedSet(groupby))
groupby_list = groupby[:1] if lazy else groupby
annotated_groupbys = [self._read_group_process_groupby(gb, query) for gb in groupby_list]
groupby_fields = [g['field'] for g in annotated_groupbys]
+23 -12
View File
@@ -4,16 +4,17 @@
""" Models registries.
"""
from collections import Mapping, defaultdict
from collections import Mapping, defaultdict, deque
from contextlib import closing
from operator import attrgetter
import logging
import os
import threading
import odoo
from .. import SUPERUSER_ID
from odoo.tools import assertion_report, lazy_classproperty, config, \
lazy_property, topological_sort, OrderedSet
from odoo.tools import (assertion_report, lazy_classproperty, config,
lazy_property, topological_sort, OrderedSet)
from odoo.tools.lru import LRU
_logger = logging.getLogger(__name__)
@@ -222,6 +223,22 @@ class Registry(Mapping):
env[model_name]._parent_store_compute()
self._init = False
def descendants(self, model_names, *kinds):
""" Return the models corresponding to ``model_names`` and all those
that inherit/inherits from them.
"""
assert all(kind in ('_inherit', '_inherits') for kind in kinds)
funcs = [attrgetter(kind + '_children') for kind in kinds]
models = OrderedSet()
queue = deque(model_names)
while queue:
model = self[queue.popleft()]
models.add(model)
for func in funcs:
queue.extend(func(model))
return models
def load(self, cr, module):
""" Load a given module in the registry, and return the names of the
modified models.
@@ -234,23 +251,17 @@ class Registry(Mapping):
"""
from .. import models
loaded_models = OrderedSet()
def mark_loaded(model):
# recursively mark model and its children
loaded_models.add(model._name)
for child_name in model._inherit_children:
mark_loaded(self[child_name])
lazy_property.reset_all(self)
# Instantiate registered classes (via the MetaModel automatic discovery
# or via explicit constructor call), and add them to the pool.
model_names = []
for cls in models.MetaModel.module_to_models.get(module.name, []):
# models register themselves in self.models
model = cls._build_model(self, cr)
mark_loaded(model)
model_names.append(model._name)
return list(loaded_models)
return self.descendants(model_names, '_inherit')
def setup_models(self, cr, partial=False):
""" Complete the setup of models.