Пример #1
0
    def __new__(cls, name, bases, attrs):

        super_new = super(ModelType, cls).__new__

        parents = [b for b in bases if isinstance(b, ModelType)]
        if not parents:
            # This is not a subclass of Model so do nothing
            return super_new(cls, name, bases, attrs)

        if len(parents) > 1:
            raise TypeError(_('Multiple inheritance is not supported.'))

        check_reserved_names(attrs)

        # always use the last defined base class in the inheritance chain
        # to maintain linear hierarchy.

        meta = getattr(parents[0], '_meta', None) or Options()

        try:
            parent = pool.get_model(meta.name) if meta.name else None
        except KeyError:
            parent = None

        if meta.package is None:
            try:
                meta.package = pool.get_package(attrs['__module__']).package.name
            except:
                meta.package = ''

        if parent:
            bases = list(bases)
            for i, base in enumerate(bases):
                if isinstance(base, ModelType):
                    bases[i] = parent
            bases = tuple(bases)

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

        # update meta information
        unique = attrs.pop('__unique__', [])
        if meta.name is None:
            meta_name = name.lower()
            if meta.package:
                meta_name = '%s:%s' % (meta.package, meta_name)
            meta.name = meta_name
            meta.table = meta_name.replace(':', '_')

        # create primary key field if it is root model
        if not parent:
            cls.add_field(AutoKey())

        # overwrite model class in the pool
        pool.register_model(cls)

        cls._values = None

        # sort fields and set attributes to class
        attributes = attrs.items()
        attributes.sort(lambda a, b: cmp(
            getattr(a[1], '_serial', 0), getattr(b[1], '_serial', 0)))

        for name, attr in attributes:
            if isinstance(attr, Field):
                cls.add_field(attr, name)
                if attr.is_unique:
                    unique.append([attr])
            else:
                setattr(cls, name, attr)

        # prepare validators
        for name, attr in attributes:
            if name.startswith('validate_') and isinstance(attr, types.FunctionType):
                field = getattr(cls, name[9:], None)
                if isinstance(field, Field):
                    field._validator = getattr(cls, name) # use bound method

        # prepare unique constraints
        for item in unique:
            item = list(item) if isinstance(item, (list, tuple)) else [item]
            for i, field in enumerate(item):
                if isinstance(field, basestring):
                    try:
                        item[i] = field = getattr(cls, field)
                    except:
                        raise AttributeError(
                            _('No such field %(name)s.', field))
                assert isinstance(field, Field), 'expected a field'
            meta.unique.append(item)

        return cls
Пример #2
0
 def package(self):
     """The name of the current package.
     """
     if self.endpoint:
         return pool.get_package(self.endpoint).package.name