[FIX] module loading: manual x2x fields can now refer to manual models

The fix consists in this: when setting up models, ignore manual fields that
refer to unknown models if all models have not been loaded yet.
This commit is contained in:
Raphael Collet 2014-08-04 11:45:11 +02:00 committed by Olivier Dony
parent 7f0353974d
commit 2d2274aeed
5 changed files with 14 additions and 5 deletions

View File

@ -263,6 +263,7 @@ class Field(object):
store = True # whether the field is stored in database store = True # whether the field is stored in database
index = False # whether the field is indexed in database index = False # whether the field is indexed in database
manual = False # whether the field is a custom field
copyable = True # whether the field is copied over by BaseModel.copy() copyable = True # whether the field is copied over by BaseModel.copy()
depends = () # collection of field dependencies depends = () # collection of field dependencies
recursive = False # whether self depends on itself recursive = False # whether self depends on itself

View File

@ -2956,9 +2956,13 @@ class BaseModel(object):
field.reset() field.reset()
@api.model @api.model
def _setup_fields(self): def _setup_fields(self, partial=False):
""" Setup the fields (dependency triggers, etc). """ """ Setup the fields (dependency triggers, etc). """
for field in self._fields.itervalues(): for field in self._fields.itervalues():
if partial and field.manual and \
field.relational and field.comodel_name not in self.pool:
# do not set up manual fields that refer to unknown models
continue
field.setup(self.env) field.setup(self.env)
# group fields by compute to determine field.computed_fields # group fields by compute to determine field.computed_fields

View File

@ -159,7 +159,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
loaded_modules.append(package.name) loaded_modules.append(package.name)
if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'): if hasattr(package, 'init') or hasattr(package, 'update') or package.state in ('to install', 'to upgrade'):
registry.setup_models(cr) registry.setup_models(cr, partial=True)
init_module_models(cr, package.name, models) init_module_models(cr, package.name, models)
# Can't put this line out of the loop: ir.module.module will be # Can't put this line out of the loop: ir.module.module will be
@ -225,7 +225,7 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
registry._init_modules.add(package.name) registry._init_modules.add(package.name)
cr.commit() cr.commit()
registry.setup_models(cr) registry.setup_models(cr, partial=True)
_logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, openerp.sql_db.sql_counter - t0_sql) _logger.log(25, "%s modules loaded in %.2fs, %s queries", len(graph), time.time() - t0, openerp.sql_db.sql_counter - t0_sql)
@ -360,6 +360,7 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
cr.execute('select model from ir_model where state=%s', ('manual',)) cr.execute('select model from ir_model where state=%s', ('manual',))
for model in cr.dictfetchall(): for model in cr.dictfetchall():
registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {}) registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {})
registry.setup_models(cr)
# STEP 4: Finish and cleanup installations # STEP 4: Finish and cleanup installations
if processed_modules: if processed_modules:

View File

@ -151,9 +151,11 @@ class Registry(Mapping):
return [self.models[m] for m in models_to_load] return [self.models[m] for m in models_to_load]
def setup_models(self, cr): def setup_models(self, cr, partial=False):
""" Complete the setup of models. """ Complete the setup of models.
This must be called after loading modules and before using the ORM. This must be called after loading modules and before using the ORM.
:param partial: ``True`` if all models have not been loaded yet.
""" """
# prepare the setup on all models # prepare the setup on all models
for model in self.models.itervalues(): for model in self.models.itervalues():
@ -162,7 +164,7 @@ class Registry(Mapping):
# do the actual setup from a clean state # do the actual setup from a clean state
self._m2m = {} self._m2m = {}
for model in self.models.itervalues(): for model in self.models.itervalues():
model._setup_fields(cr, SUPERUSER_ID) model._setup_fields(cr, SUPERUSER_ID, partial=partial)
def clear_caches(self): def clear_caches(self):
""" Clear the caches """ Clear the caches

View File

@ -134,6 +134,7 @@ class _column(object):
('_origin', self), # field interfaces self ('_origin', self), # field interfaces self
('copy', self.copy), ('copy', self.copy),
('index', self.select), ('index', self.select),
('manual', self.manual),
('string', self.string), ('string', self.string),
('help', self.help), ('help', self.help),
('readonly', self.readonly), ('readonly', self.readonly),