[MERGE] forward port branch saas-12 up to b1b700a
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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::
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user