Пример #1
0
    def __new__(cls, name, bases, attrs):
        #print '%s.__new__(%s)' % (name, cls)
        req_sub = attrs.pop('__requires_subclass__', False)

        super_new = super(ModelBase, cls).__new__

        parents = [b for b in bases if isinstance(b, ModelBase) and
            not (b.__name__ == 'Base' and b.__mro__ == (b, object))]
        if not parents:
            return super_new(cls, name, bases, attrs)

        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})

        # check the class registry to see if we created this already
        if name in new_class._decl_class_registry:
            return new_class._decl_class_registry[name]

        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, '_meta', None)

        if getattr(meta, 'app_label', None) is None:
            model_module = sys.modules[new_class.__module__]
            kwargs = {"app_label": model_module.__name__.rsplit('.',1)[0]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if base_meta:
            for k,v in vars(base_meta).items():
                if not getattr(new_class._meta, k, None):
                    setattr(new_class._meta, k, v)

        if new_class._meta.swappable:
            if not new_class._meta.swapped:
                # class is swappable, but hasn't been swapped out, so we create
                # an alias to the base class, rather than trying to create a new
                # class under a second name
                base_cls  = bases[0]
                base_cls.add_to_class('_meta', new_class._meta)
                register_models(base_cls._meta.app_label, base_cls)
                return base_cls

            # class has been swapped out
            model = safe_import(new_class._meta.swapped, [new_class.__module__])

            for b in bases:
                if not getattr(b, '__mapper__', None):
                    continue
                if not getattr(b, '_sa_class_manager', None):
                    continue
                subs = [c for c in b.__subclasses__() if c.__name__ != name]
                if any(c.__name__ != name for c in b.__subclasses__()):
                    # this base class has a subclass inheriting from it, so we
                    # should leave this class alone, we'll need it
                    continue
                else:
                    # this base class is used by no subclasses, so it can be
                    # removed from appcache/cls registry/mod registry
                    remove_class(b, name)
            return model

        if attrs.get('__tablename__') and not attrs.get('__abstract__', None):
          # build the table_args for the current model
          #print '[%s]' % name
          base_args = getattr(settings, 'BAPH_DEFAULT_TABLE_ARGS', ())
          _, kwargs = normalize_args(base_args)
          for p in reversed(parents):
            if not hasattr(p, '__table_args__'):
              continue
            _, _kwargs = normalize_args(p.__table_args__)
            kwargs.update(_kwargs)
          table_args = attrs.pop('__table_args__', None)
          #print '  old:', table_args
          args, _kwargs = normalize_args(table_args)
          kwargs.update(_kwargs)
          attrs['__table_args__'] = args + (kwargs,)
          #print '  new:', attrs['__table_args__']

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        if attrs.get('__abstract__', None):
            return new_class

        signals.class_prepared.send(sender=new_class)
        register_models(new_class._meta.app_label, new_class)
        return get_model(new_class._meta.app_label, name,
                         seed_cache=False, only_installed=False)
Пример #2
0
    def __new__(cls, name, bases, attrs):
        #print '%s.__new__(%s)' % (name, cls)
        req_sub = attrs.pop('__requires_subclass__', False)

        super_new = super(ModelBase, cls).__new__

        parents = [
            b for b in bases if isinstance(b, ModelBase)
            and not (b.__name__ == 'Base' and b.__mro__ == (b, object))
        ]
        if not parents:
            return super_new(cls, name, bases, attrs)

        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})

        # check the class registry to see if we created this already
        if name in new_class._decl_class_registry:
            return new_class._decl_class_registry[name]

        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
        base_meta = getattr(new_class, '_meta', None)

        if getattr(meta, 'app_label', None) is None:
            # Figure out the app_label by looking one level up.
            # For 'django.contrib.sites.models', this would be 'sites'.
            model_module = sys.modules[new_class.__module__]
            kwargs = {"app_label": model_module.__name__.rsplit('.', 1)[0]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if base_meta:
            for k, v in vars(base_meta).items():
                if not getattr(new_class._meta, k, None):
                    setattr(new_class._meta, k, v)

        if new_class._meta.swappable:
            if not new_class._meta.swapped:
                # class is swappable, but hasn't been swapped out, so we create
                # an alias to the base class, rather than trying to create a new
                # class under a second name
                base_cls = bases[0]
                base_cls.add_to_class('_meta', new_class._meta)
                register_models(base_cls._meta.app_label, base_cls)
                return base_cls

            # class has been swapped out
            model = safe_import(new_class._meta.swapped,
                                [new_class.__module__])

            for b in bases:
                if not getattr(b, '__mapper__', None):
                    continue
                if not getattr(b, '_sa_class_manager', None):
                    continue
                subs = [c for c in b.__subclasses__() if c.__name__ != name]
                if any(c.__name__ != name for c in b.__subclasses__()):
                    # this base class has a subclass inheriting from it, so we
                    # should leave this class alone, we'll need it
                    continue
                else:
                    # this base class is used by no subclasses, so it can be
                    # removed from appcache/cls registry/mod registry
                    remove_class(b, name)
            return model

        # Add all attributes to the class.
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)

        if attrs.get('__abstract__', None):
            return new_class

        signals.class_prepared.send(sender=new_class)
        register_models(new_class._meta.app_label, new_class)
        return get_model(new_class._meta.app_label,
                         name,
                         seed_cache=False,
                         only_installed=False)