diff --git a/openerp/addons/base/ir/ir_model.py b/openerp/addons/base/ir/ir_model.py index 96819f918dc..ae1ffce2fc4 100644 --- a/openerp/addons/base/ir/ir_model.py +++ b/openerp/addons/base/ir/ir_model.py @@ -446,6 +446,7 @@ class ir_model_fields(osv.osv): for item in self.browse(cr, user, ids, context=context): obj = self.pool.get(item.model) + field = getattr(obj, '_fields', {}).get(item.name) if item.state != 'manual': raise except_orm(_('Error!'), @@ -481,12 +482,12 @@ class ir_model_fields(osv.osv): # We don't check the 'state', because it might come from the context # (thus be set for multiple fields) and will be ignored anyway. - if obj is not None: + if obj is not None and field is not None: # find out which properties (per model) we need to update for field_name, prop_name, func in model_props: if field_name in vals: prop_value = func(vals[field_name]) - if getattr(obj._fields[item.name], prop_name) != prop_value: + if getattr(field, prop_name) != prop_value: patches[obj][final_name][prop_name] = prop_value # These shall never be written (modified) diff --git a/openerp/models.py b/openerp/models.py index e995e87b4e9..028cffbc392 100644 --- a/openerp/models.py +++ b/openerp/models.py @@ -705,7 +705,7 @@ class BaseModel(object): pool._store_function[model].sort(key=lambda x: x[4]) @classmethod - def _init_manual_fields(cls, cr): + def _init_manual_fields(cls, cr, partial=False): # Check whether the query is already done if cls.pool.fields_by_model is not None: manual_fields = cls.pool.fields_by_model.get(cls._name, []) @@ -729,14 +729,20 @@ class BaseModel(object): elif field['ttype'] in ('selection', 'reference'): attrs['selection'] = eval(field['selection']) elif field['ttype'] == 'many2one': + if partial and field['relation'] not in cls.pool: + continue attrs['comodel_name'] = field['relation'] attrs['ondelete'] = field['on_delete'] attrs['domain'] = eval(field['domain']) if field['domain'] else None elif field['ttype'] == 'one2many': + if partial and field['relation'] not in cls.pool: + continue attrs['comodel_name'] = field['relation'] attrs['inverse_name'] = field['relation_field'] attrs['domain'] = eval(field['domain']) if field['domain'] else None elif field['ttype'] == 'many2many': + if partial and field['relation'] not in cls.pool: + continue attrs['comodel_name'] = field['relation'] _rel1 = field['relation'].replace('.', '_') _rel2 = field['model'].replace('.', '_') @@ -2939,8 +2945,11 @@ class BaseModel(object): field.reset() @api.model - def _setup_fields(self): - """ Setup the fields (dependency triggers, etc). """ + def _setup_fields(self, partial=False): + """ Setup the fields (dependency triggers, etc). + + :param partial: ``True`` if all models have not been loaded yet. + """ cls = type(self) if cls._setup_done: return @@ -2951,8 +2960,7 @@ class BaseModel(object): self.env[parent]._setup_fields() # retrieve custom fields - if not self._context.get('_setup_fields_partial'): - cls._init_manual_fields(self._cr) + cls._init_manual_fields(self._cr, partial=partial) # retrieve inherited fields cls._inherits_check() diff --git a/openerp/modules/loading.py b/openerp/modules/loading.py index 006a077a92d..c6123f82560 100644 --- a/openerp/modules/loading.py +++ b/openerp/modules/loading.py @@ -360,10 +360,6 @@ def load_modules(db, force_demo=False, status=None, update_module=False): ['to install'], force, status, report, loaded_modules, update_module) - # load custom models - cr.execute('select model from ir_model where state=%s', ('manual',)) - for model in cr.dictfetchall(): - registry['ir.model'].instanciate(cr, SUPERUSER_ID, model['model'], {}) registry.setup_models(cr) # STEP 4: Finish and cleanup installations diff --git a/openerp/modules/registry.py b/openerp/modules/registry.py index afdb48fe304..e1a14d52210 100644 --- a/openerp/modules/registry.py +++ b/openerp/modules/registry.py @@ -158,15 +158,20 @@ class Registry(Mapping): :param partial: ``True`` if all models have not been loaded yet. """ + # load custom models + ir_model = self['ir.model'] + cr.execute('select model from ir_model where state=%s', ('manual',)) + for (model_name,) in cr.fetchall(): + ir_model.instanciate(cr, SUPERUSER_ID, model_name, {}) + # prepare the setup on all models for model in self.models.itervalues(): model._prepare_setup_fields(cr, SUPERUSER_ID) # do the actual setup from a clean state self._m2m = {} - context = {'_setup_fields_partial': partial} for model in self.models.itervalues(): - model._setup_fields(cr, SUPERUSER_ID, context=context) + model._setup_fields(cr, SUPERUSER_ID, partial=partial) def clear_caches(self): """ Clear the caches