diff --git a/openerp/osv/orm.py b/openerp/osv/orm.py index 064ab16bbfd..b48cf6cf047 100644 --- a/openerp/osv/orm.py +++ b/openerp/osv/orm.py @@ -416,6 +416,32 @@ def get_pg_type(f): return f_type +class MetaModel(type): + """ Metaclass for the Model. + + This class is used as the metaclass for the Model class to discover + the models defined in a module (i.e. without instanciating them). + If the automatic discovery is not needed, it is possible to set the + model's _register attribute to False. + + """ + + module_to_models = {} + + def __init__(self, name, bases, attrs): + if not self._register: + self._register = True + super(MetaModel, self).__init__(name, bases, attrs) + return + + module_name = self.__module__.split('.')[0] + if not hasattr(self, '_module'): + self._module = module_name + + # Remember which models to instanciate for this module. + self.module_to_models.setdefault(self._module, []).append(self) + + class orm_template(object): """ Base class for OpenERP models. @@ -647,7 +673,7 @@ class orm_template(object): else: new.extend(cls.__dict__.get(s, [])) nattr[s] = new - cls = type(name, (cls, parent_class), nattr) + cls = type(name, (cls, parent_class), dict(nattr, _register=False)) obj = object.__new__(cls) obj.__init__(pool, cr) return obj diff --git a/openerp/osv/osv.py b/openerp/osv/osv.py index ae25d82893b..bdc89a96676 100644 --- a/openerp/osv/osv.py +++ b/openerp/osv/osv.py @@ -35,6 +35,8 @@ from psycopg2 import IntegrityError, errorcodes from openerp.tools.func import wraps from openerp.tools.translate import translate from openerp.osv.orm import module_class_list +from openerp.osv.orm import MetaModel + class except_osv(Exception): def __init__(self, name, value, exc_type='warning'): @@ -245,17 +247,24 @@ class osv_pool(object): for klass in module_class_list.get(module, []): res.append(klass.createInstance(self, cr)) + # Instanciate classes automatically discovered. + for cls in MetaModel.module_to_models.get(module, []): + if cls not in module_class_list.get(module, []): + res.append(cls.createInstance(self, cr)) + return res class osv_memory(orm.orm_memory): """ Deprecated class. """ - pass + __metaclass__ = MetaModel + _register = False # Set to false if the model shouldn't be automatically discovered. class osv(orm.orm): """ Deprecated class. """ - pass + __metaclass__ = MetaModel + _register = False # Set to false if the model shouldn't be automatically discovered. def start_object_proxy():