示例#1
0
    def __new__(cls, name, bases, attrs):
        super_new = super(XmlModelBase, cls).__new__
        parents = [b for b in bases if isinstance(b, XmlModelBase)]
        if not parents:
            # If this isn't a subclass of Model, don't do anything special.
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        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__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))

        new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
                tuple(x.DoesNotExist
                        for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                or (ObjectDoesNotExist,), module))
        new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
                tuple(x.MultipleObjectsReturned
                        for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                or (MultipleObjectsReturned,), module))

        # Bail out early if we have already created this class.
        m = get_xml_model(new_class._meta.app_label, name, False)
        if m is not None:
            return m

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

        new_class._prepare()
        register_xml_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_xml_model(new_class._meta.app_label, name, False)
示例#2
0
    def _prepare(self):
        super(TenantModelBase, self)._prepare()

        if issubclass(self, TenantSpecificModel):
            for_tenant_model = self._for_tenant_model

            # Attach the tenant model concrete managers since they should
            # override the ones from abstract bases.
            managers = for_tenant_model._meta.concrete_managers
            for _, mgr_name, manager in managers:
                new_manager = manager._copy_to_model(self)
                new_manager.creation_counter = manager.creation_counter
                self.add_to_class(mgr_name, new_manager)

            # Since our declaration class is not one of our parents we must
            # make sure our exceptions extend his.
            for exception in self.exceptions:
                subclass = subclass_exception(
                    str(exception),
                    (getattr(self,
                             exception), getattr(for_tenant_model, exception)),
                    self.__module__,
                    self,
                )
                self.add_to_class(exception, subclass)
 def obj_get(self, request=None, **kwargs):
     # MongoEngine exceptions are separate from Django exceptions, we combine them here
     try:
         return super(MongoEngineResource, self).obj_get(request, **kwargs)
     except self._meta.object_class.DoesNotExist, e:
         exp = base.subclass_exception('DoesNotExist', (self._meta.object_class.DoesNotExist, exceptions.ObjectDoesNotExist), self._meta.object_class.DoesNotExist.__module__)
         raise exp(*e.args)
示例#4
0
    def _prepare(self):
        super(TenantModelBase, self)._prepare()

        if issubclass(self, TenantSpecificModel):
            for_tenant_model = self._for_tenant_model

            # TODO: Remove when dropping support for Django < 1.10
            if django.VERSION >= (1, 10):
                for mgr_name, manager in for_tenant_model._meta.managers_map.items():
                    new_manager = copy.copy(manager)
                    new_manager.creation_counter = manager.creation_counter
                    self.add_to_class(mgr_name, new_manager)
            else:
                for _, mgr_name, manager in for_tenant_model._meta.concrete_managers:
                    new_manager = manager._copy_to_model(self)
                    new_manager.creation_counter = manager.creation_counter
                    self.add_to_class(mgr_name, new_manager)

            # Since our declaration class is not one of our parents we must
            # make sure our exceptions extend his.
            for exception in self.exceptions:
                subclass = subclass_exception(
                    str(exception),
                    (getattr(self, exception), getattr(for_tenant_model, exception)),
                    self.__module__,
                    self,
                )
                self.add_to_class(exception, subclass)
示例#5
0
    def _prepare(self):
        super(TenantModelBase, self)._prepare()

        if issubclass(self, TenantSpecificModel):
            for_tenant_model = self._for_tenant_model

            # TODO: Remove when dropping support for Django < 1.10
            if django.VERSION >= (1, 10):
                for mgr_name, manager in for_tenant_model._meta.managers_map.items():
                    new_manager = copy.copy(manager)
                    new_manager.creation_counter = manager.creation_counter
                    self.add_to_class(mgr_name, new_manager)
            else:
                for _, mgr_name, manager in for_tenant_model._meta.concrete_managers:
                    new_manager = manager._copy_to_model(self)
                    new_manager.creation_counter = manager.creation_counter
                    self.add_to_class(mgr_name, new_manager)

            # Since our declaration class is not one of our parents we must
            # make sure our exceptions extend his.
            for exception in self.exceptions:
                subclass = subclass_exception(
                    str(exception),
                    (getattr(self, exception), getattr(for_tenant_model, exception)),
                    self.__module__,
                    self,
                )
                self.add_to_class(exception, subclass)
 def obj_get(self, request=None, **kwargs):
     # MongoEngine exceptions are separate from Django exceptions, we combine them here
     try:
         return super(MongoEngineResource, self).obj_get(request, **kwargs)
     except self._meta.object_class.DoesNotExist, e:
         exp = models_base.subclass_exception(
             'DoesNotExist', (self._meta.object_class.DoesNotExist,
                              exceptions.ObjectDoesNotExist),
             self._meta.object_class.DoesNotExist.__module__)
         raise exp(*e.args)
 def obj_get(self, bundle, **kwargs):
     # MongoEngine exceptions are separate from Django exceptions, we combine them here
     try:
         return super(MongoEngineResource, self).obj_get(bundle=bundle, **kwargs)
     except self._meta.object_class.DoesNotExist as ex:
         exp = models_base.subclass_exception('DoesNotExist', (self._meta.object_class.DoesNotExist, exceptions.ObjectDoesNotExist), self._meta.object_class.DoesNotExist.__module__)
         raise exp(*ex.args)
     except queryset.DoesNotExist as ex:
         exp = models_base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
         raise exp(*ex.args)
     except self._meta.object_class.MultipleObjectsReturned as ex:
         exp = models_base.subclass_exception('MultipleObjectsReturned', (self._meta.object_class.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), self._meta.object_class.MultipleObjectsReturned.__module__)
         raise exp(*ex.args)
     except queryset.MultipleObjectsReturned as ex:
         exp = models_base.subclass_exception('MultipleObjectsReturned', (queryset.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), queryset.MultipleObjectsReturned.__module__)
         raise exp(*ex.args)
     except mongoengine.ValidationError as ex:
         exp = models_base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
         raise exp(*ex.args)
示例#8
0
 def obj_get(self, bundle, **kwargs):
     # MongoEngine exceptions are separate from Django exceptions, we combine them here
     try:
         return super(MongoEngineResource, self).obj_get(bundle=bundle, **kwargs)
     except self._meta.object_class.DoesNotExist as ex:
         exp = models_base.subclass_exception('DoesNotExist', (self._meta.object_class.DoesNotExist, exceptions.ObjectDoesNotExist), self._meta.object_class.DoesNotExist.__module__)
         raise exp(*ex.args)
     except queryset.DoesNotExist as ex:
         exp = models_base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
         raise exp(*ex.args)
     except self._meta.object_class.MultipleObjectsReturned as ex:
         exp = models_base.subclass_exception('MultipleObjectsReturned', (self._meta.object_class.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), self._meta.object_class.MultipleObjectsReturned.__module__)
         raise exp(*ex.args)
     except queryset.MultipleObjectsReturned as ex:
         exp = models_base.subclass_exception('MultipleObjectsReturned', (queryset.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), queryset.MultipleObjectsReturned.__module__)
         raise exp(*ex.args)
     except mongoengine.ValidationError as ex:
         exp = models_base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
         raise exp(*ex.args)
示例#9
0
def generate_child_partition(parent, num):
    opts = parent._meta
    partition_name = '%s_Partition%s' % (parent.__name__, num)

    # HACK: Attempting to initialize a model twice results in a broken model
    # even though ModelBase is supposed to handle this case already.  Instead,
    # we explicitly check to make sure the model wasn't created yet by
    # using get_model to prevent this case.
    app_label = parent._meta.app_label
    m = loading.get_model(app_label, partition_name, seed_cache=False)
    if m is not None:
        return m

    partition = ModelBase(partition_name, (parent,), {
        '__module__': parent.__module__,
        'objects': Manager(),
        'Meta': type('Meta', (object,), {
            'managed': True,
            'db_table': '%s_%s' % (parent._meta.db_table, num),
            'unique_together': opts.unique_together,
        }),
        '_shards': ShardOptions(parent=parent, num=num),
    })
    partition.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (parent.DoesNotExist,), parent.__module__))
    partition.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned', (parent.MultipleObjectsReturned,), parent.__module__))

    # Connect signals so we can re-send them
    signaler = resend_signal(parent)
    for signal in (signals.pre_save, signals.post_save, signals.pre_delete, signals.post_delete,
                   signals.pre_init, signals.post_init, signals.m2m_changed):
        signal.connect(signaler, sender=partition, weak=False)

    # Ensure the partition is available within the module scope
    module = sys.modules[parent.__module__]
    setattr(module, partition.__name__, partition)

    # Register all partitions with Django
    loading.register_models(app_label, partition)

    return partition
示例#10
0
    def _prepare(self):
        super(TenantModelBase, self)._prepare()

        if issubclass(self, TenantSpecificModel):
            for_tenant_model = self._for_tenant_model

            # Attach the tenant model concrete managers since they should
            # override the ones from abstract bases.
            managers = for_tenant_model._meta.concrete_managers
            for _, mgr_name, manager in managers:
                new_manager = manager._copy_to_model(self)
                new_manager.creation_counter = manager.creation_counter
                self.add_to_class(mgr_name, new_manager)

            # Since our declaration class is not one of our parents we must
            # make sure our exceptions extend his.
            for exception in self.exceptions:
                self.add_to_class(exception, subclass_exception(str(exception),
                    (getattr(self, exception),
                     getattr(for_tenant_model, exception)),
                    self.__module__, self
                ))
示例#11
0
    def __new__(cls, name, bases, attrs):
        # Force this model to be abstract as it's not a real table
        if 'Meta' not in attrs:
            is_abstract = False
            attrs['Meta'] = type('Meta', (object,), {
                'abstract': True,
            })
        else:
            is_abstract = getattr(attrs['Meta'], 'abstract', False)
            attrs['Meta'].abstract = True

        attrs['objects'] = MasterPartitionManager()

        new_cls = super(PartitionDescriptor, cls).__new__(cls, name, bases, attrs)

        attr_shardopts = attrs.pop('Shards', None)

        # HACK: non-abstract inheritance is not supported due to issues with metaclass
        # recursion
        if not any(b._shards.abstract if hasattr(b, '_shards') else True for b in bases):
            return new_cls

        if not attr_shardopts:
            shardopts = getattr(new_cls, 'Shards', None)
        else:
            shardopts = attr_shardopts
        base_shardopts = getattr(new_cls, '_shards', None)

        shards = []
        new_cls.add_to_class('_shards', MasterShardOptions(shardopts, nodes=shards))

        if base_shardopts:
            for k in DEFAULT_NAMES:
                if not hasattr(new_cls._shards, k):
                    setattr(new_cls._shards, k, getattr(base_shardopts, k, None))

        # We record the true abstract switch as part of _shards
        new_cls._shards.abstract = is_abstract

        if is_abstract:
            return new_cls

        # Some basic validation
        for k in DEFAULT_NAMES:
            if getattr(new_cls._shards, k, None) is None:
                raise ValidationError('Missing shard configuration value for %r on %r.' % (k, new_cls))

        new_cls.add_to_class('DoesNotExist', subclass_exception('DoesNotExist', (ObjectDoesNotExist,), new_cls.__module__))
        new_cls.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned', (MultipleObjectsReturned,), new_cls.__module__))

        # Because we're an abstract model, we must also fake our own registration
        app_label = new_cls._meta.app_label
        loading.register_models(app_label, new_cls)

        new_cls._really_prepare()

        # We need to create a model for each partition instance which is assigned to the
        # appropriate table
        for n in xrange(new_cls._shards.num_shards):
            partition = generate_child_partition(new_cls, n)

            # Add to list of partitions for this master
            shards.append(partition)

        return new_cls
示例#12
0
    def __new__(mcs, name, bases, attrs, **kwargs):
        super_new = super().__new__

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [b for b in bases if isinstance(b, ModelMeta)]
        if not parents:
            return super_new(mcs, name, bases, attrs, **kwargs)

        # Create the class.
        module = attrs.pop('__module__')
        new_attrs = {'__module__': module}
        classcell = attrs.pop('__classcell__', None)
        if classcell is not None:
            new_attrs['__classcell__'] = classcell
        attr_meta = attrs.pop('Meta', None)
        # Pass all attrs without a (Django-specific) contribute_to_class()
        # method to type.__new__() so that they're properly initialized
        # (i.e. __set_name__()).
        contributable_attrs = {}
        for obj_name, obj in list(attrs.items()):
            if _has_contribute_to_class(obj):
                contributable_attrs[obj_name] = obj
            else:
                new_attrs[obj_name] = obj
        new_class = super_new(mcs, name, bases, new_attrs, **kwargs)

        abstract = getattr(attr_meta, 'abstract', False)
        meta = attr_meta or getattr(new_class, 'Meta', None)
        base_meta = getattr(new_class, '_meta', None)

        app_label = None

        new_class.add_to_class('_meta', Options(meta, app_label))
        if not abstract:
            new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    'DoesNotExist',
                    tuple(x.DoesNotExist for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (ObjectDoesNotExist, ),
                    module,
                    attached_to=new_class))
            new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    'MultipleObjectsReturned',
                    tuple(x.MultipleObjectsReturned for x in parents
                          if hasattr(x, '_meta') and not x._meta.abstract)
                    or (MultipleObjectsReturned, ),
                    module,
                    attached_to=new_class))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." %
                            (name, base_meta.swapped))

        # Add remaining attributes (those with a contribute_to_class() method)
        # to the class.
        for obj_name, obj in contributable_attrs.items():
            new_class.add_to_class(obj_name, obj)

        # All the fields of any type declared on this model
        new_fields = chain(new_class._meta.local_fields,
                           new_class._meta.local_many_to_many,
                           new_class._meta.private_fields)
        field_names = {f.name for f in new_fields}

        # Basic setup for proxy models.
        new_class._meta.concrete_model = new_class

        # Collect the parent links for multi-table inheritance.
        parent_links = {}
        for base in reversed([new_class] + parents):
            # Conceptually equivalent to `if base is Model`.
            if not hasattr(base, '_meta'):
                continue
            # Skip concrete parent classes.
            if base != new_class and not base._meta.abstract:
                continue
            # Locate OneToOneField instances.
            for field in base._meta.local_fields:
                if isinstance(
                        field,
                        OneToOneField) and field.remote_field.parent_link:
                    related = resolve_relation(new_class,
                                               field.remote_field.model)
                    parent_links[make_model_tuple(related)] = field

        # Track fields inherited from base models.
        inherited_attributes = set()
        # Do the appropriate setup for any model parents.
        for base in new_class.mro():
            if base not in parents or not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                inherited_attributes.update(base.__dict__)
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            if not base._meta.abstract:
                # Check for clashes between locally declared fields and those
                # on the base classes.
                for field in parent_fields:
                    if field.name in field_names:
                        raise FieldError(
                            'Local field %r in class %r clashes with field of '
                            'the same name from base class %r.' % (
                                field.name,
                                name,
                                base.__name__,
                            ))
                    else:
                        inherited_attributes.add(field.name)

                # Concrete classes...
                base = base._meta.concrete_model
                base_key = make_model_tuple(base)
                if base_key in parent_links:
                    field = parent_links[base_key]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(
                        base,
                        on_delete=CASCADE,
                        name=attr_name,
                        auto_created=True,
                        parent_link=True,
                    )

                    if attr_name in field_names:
                        raise FieldError(
                            "Auto-generated field '%s' in class %r for "
                            "parent_link to base class %r clashes with "
                            "declared field of the same name." % (
                                attr_name,
                                name,
                                base.__name__,
                            ))

                    # Only add the ptr field if it's not already present;
                    # e.g. migrations will already have it specified
                    if not hasattr(new_class, attr_name):
                        new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                base_parents = base._meta.parents.copy()

                # Add fields from abstract base class if it wasn't overridden.
                for field in parent_fields:
                    if (field.name not in field_names
                            and field.name not in new_class.__dict__
                            and field.name not in inherited_attributes):
                        new_field = copy.deepcopy(field)
                        new_class.add_to_class(field.name, new_field)
                        # Replace parent links defined on this base by the new
                        # field. It will be appropriately resolved if required.
                        if field.one_to_one:
                            for parent, parent_link in base_parents.items():
                                if field == parent_link:
                                    base_parents[parent] = new_field

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base_parents)

            # Inherit private fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.private_fields:
                if field.name in field_names:
                    if not base._meta.abstract:
                        raise FieldError(
                            'Local field %r in class %r clashes with field of '
                            'the same name from base class %r.' % (
                                field.name,
                                name,
                                base.__name__,
                            ))
                else:
                    field = copy.deepcopy(field)
                    if not base._meta.abstract:
                        field.mti_inherited = True
                    new_class.add_to_class(field.name, field)

        # Copy indexes so that index names are unique when models extend an
        # abstract model.
        new_class._meta.indexes = [
            copy.deepcopy(idx) for idx in new_class._meta.indexes
        ]

        new_class._prepare()
        return new_class
        data.update({
            'resource_types': type_map.keys(),
        })

        return data

    def obj_get(self, request=None, **kwargs):
        # MongoEngine exceptions are separate from Django exceptions, we combine them here
        try:
            return super(MongoEngineResource, self).obj_get(request, **kwargs)
        except self._meta.object_class.DoesNotExist, e:
            exp = base.subclass_exception('DoesNotExist', (self._meta.object_class.DoesNotExist, exceptions.ObjectDoesNotExist), self._meta.object_class.DoesNotExist.__module__)
            raise exp(*e.args)
        except queryset.DoesNotExist, e:
            exp = base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
            raise exp(*e.args)
        except self._meta.object_class.MultipleObjectsReturned, e:
            exp = base.subclass_exception('MultipleObjectsReturned', (self._meta.object_class.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), self._meta.object_class.MultipleObjectsReturned.__module__)
            raise exp(*e.args)
        except queryset.MultipleObjectsReturned, e:
            exp = base.subclass_exception('MultipleObjectsReturned', (queryset.MultipleObjectsReturned, exceptions.MultipleObjectsReturned), queryset.MultipleObjectsReturned.__module__)
            raise exp(*e.args)
        except mongoengine.ValidationError, e:
            exp = base.subclass_exception('DoesNotExist', (queryset.DoesNotExist, exceptions.ObjectDoesNotExist), queryset.DoesNotExist.__module__)
            raise exp(*e.args)

    def obj_update(self, bundle, request=None, **kwargs):
        if not bundle.obj or not getattr(bundle.obj, 'pk', None):
            try:
                bundle.obj = self.obj_get(request, **kwargs)
示例#14
0
    def __new__(cls, name, bases, attrs):
        new_class = super(BrushfireModelBase, cls).__new__(cls, name, bases, attrs)
        
        parents = [b for b in bases if isinstance(b, BrushfireModelBase)]

        module = attrs.pop('__module__')
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta
            
        app_config = apps.get_containing_app_config(module)
        setattr(new_class, 'objects', BrushfireManager(new_class))
        
        if getattr(meta, 'app_label', None):
            label = meta.app_label
        elif app_config:
            label = app_config.label
        else:
            label = '__NONE__'
            
        new_class.add_to_class('_meta', Options(meta, 
                **{'app_label':label}))
            
        new_class.add_to_class(
                'DoesNotExist',
                subclass_exception(
                    str('DoesNotExist'),
                    (ObjectDoesNotExist,),
                    module,
                    attached_to=new_class))
        new_class.add_to_class(
                'MultipleObjectsReturned',
                subclass_exception(
                    str('MultipleObjectsReturned'),
                    (MultipleObjectsReturned,),
                    module,
                    attached_to=new_class))

        if new_class._meta.proxy:
            raise BrushfireException, "BrushfireModels proxies not allowed."
                
        # add attributes to class
        for obj_name, obj in attrs.items():
            new_class.add_to_class(obj_name, obj)
                
        new_fields = chain(
                new_class._meta.local_fields,
                new_class._meta.local_many_to_many,
                new_class._meta.virtual_fields
        )
        field_names =  {f.name for f in new_fields}
        
        new_class._meta.concrete_model = new_class
        
        # Do the appropriate setup for any model parents.
        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError(
                        'Local field %r in class %r clashes '
                        'with field of similar name from '
                        'base class %r' % (field.name, name, base.__name__)
                    )
            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError(
                        'Local field %r in class %r clashes '
                        'with field of similar name from '
                        'abstract base class %r' % (field.name, name, base.__name__)
                    )
                new_class.add_to_class(field.name, copy.deepcopy(field))

        # Keep this stuff last
        new_class._prepare()
        # ModelBase calls this, not sure what it does or if we need it here. Need to investigate further.
        #new_class._meta.apps.register_model(new_class._meta.app_label, new_class)
        return new_class
示例#15
0
from billiard.serialization import find_nearest_pickleable_exception as fnpe
from billiard.serialization import UnpickleableExceptionWrapper
from billiard.serialization import get_pickleable_exception as gpe

from celery import states
from celery.backends.base import BaseBackend, KeyValueStoreBackend


class wrapobject(object):

    def __init__(self, *args, **kwargs):
        self.args = args


Oldstyle = types.ClassType("Oldstyle", (), {})
Unpickleable = subclass_exception("Unpickleable", KeyError, "foo.module")
Impossible = subclass_exception("Impossible", object, "foo.module")
Lookalike = subclass_exception("Lookalike", wrapobject, "foo.module")
b = BaseBackend()


class TestBaseBackendInterface(unittest.TestCase):

    def test_get_status(self):
        self.assertRaises(NotImplementedError,
                b.is_successful, "SOMExx-N0Nex1stant-IDxx-")

    def test_store_result(self):
        self.assertRaises(NotImplementedError,
                b.store_result, "SOMExx-N0nex1stant-IDxx-", 42, states.SUCCESS)
示例#16
0
    def __new__(cls, name, bases, attrs):
        super_new = super(ModelBase, cls).__new__
        parents = [b for b in bases if isinstance(b, ModelBase)]
        if not parents:
            # If this isn't a subclass of Model, don't do anything special.
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        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__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', SemanticOptions(meta, **kwargs))
        if not abstract:
            new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
                    tuple(x.DoesNotExist
                            for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                    or (ObjectDoesNotExist,), module))
            new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
                    tuple(x.MultipleObjectsReturned
                            for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                                    or (MultipleObjectsReturned,), module))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        if getattr(new_class, '_default_manager', None):
            if not is_proxy:
                # Multi-table inheritance doesn't inherit default manager from
                # parents.
                new_class._default_manager = None
                new_class._base_manager = None
            else:
                # Proxy classes do inherit parent's default manager, if none is
                # set explicitly.
                new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
                new_class._base_manager = new_class._base_manager._copy_to_model(new_class)

        # Bail out early if we have already created this class.
        m = get_model(new_class._meta.app_label, name, False)
        if m is not None:
            return m

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

        # All the fields of any type declared on this model
        new_fields = new_class._meta.local_fields + \
                     new_class._meta.local_many_to_many + \
                     new_class._meta.virtual_fields
        field_names = set([f.name for f in new_fields])

        # Basic setup for proxy models.
        if is_proxy:
            base = None
            for parent in [cls for cls in parents if hasattr(cls, '_meta')]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name)
                    else:
                        continue
                if base is not None:
                    raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
                else:
                    base = parent
            if base is None:
                    raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
            if (new_class._meta.local_fields or
                    new_class._meta.local_many_to_many):
                raise FieldError("Proxy model '%s' contains model fields." % name)
            while base._meta.proxy:
                base = base._meta.proxy_for_model
            new_class._meta.setup_proxy(base)

        # Do the appropriate setup for any model parents.
        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
                if isinstance(f, OneToOneField)])

        for base in parents:
            original_base = base
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                        (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                while base._meta.proxy:
                    # Skip over a proxy class to the "real" base it proxies.
                    base = base._meta.proxy_for_model
                if base in o2o_map:
                    field = o2o_map[base]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.module_name
                    field = OneToOneField(base, name=attr_name,
                            auto_created=True, parent_link=True)
                    new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Proxy models inherit the non-abstract managers from their base,
            # unless they have redefined any of them.
            if is_proxy:
                new_class.copy_managers(original_base._meta.concrete_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '\
                                     'with field of similar name from '\
                                     'abstract base class %r' % \
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        register_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_model(new_class._meta.app_label, name, False)
示例#17
0
class MongoEngineResource(resources.ModelResource):
    """
    Adaptation of ``ModelResource`` to MongoEngine.
    """

    __metaclass__ = MongoEngineModelDeclarativeMetaclass

    def dispatch_subresource(self, request, subresource_name, **kwargs):
        field = self.fields[subresource_name]
        resource = field.to_class(self._meta.api_name)
        return resource.dispatch(request=request, **kwargs)

    def base_urls(self):
        base = super(MongoEngineResource, self).base_urls()

        embedded_urls = []
        embedded = ((name, obj) for name, obj in self.fields.iteritems()
                    if isinstance(obj, fields.EmbeddedListField))

        for name, obj in embedded:
            embedded_urls.extend((
                urls.url(
                    r"^(?P<resource_name>%s)/(?P<pk>\w[\w-]*)/(?P<subresource_name>%s)%s$"
                    % (self._meta.resource_name, name, utils.trailing_slash()),
                    self.wrap_view('dispatch_subresource'),
                    {'request_type': 'list'},
                    name='api_dispatch_subresource_list',
                ),
                urls.url(
                    r"^(?P<resource_name>%s)/(?P<pk>\w[\w-]*)/(?P<subresource_name>%s)/(?P<subresource_pk>\w[\w-]*)%s$"
                    % (self._meta.resource_name, name, utils.trailing_slash()),
                    self.wrap_view('dispatch_subresource'),
                    {'request_type': 'detail'},
                    name='api_dispatch_subresource_detail',
                ),
            ))

        return embedded_urls + base

    def _reset_collection(self):
        """
        Because MongoEngine creates collection connection when queryset object is initialized,
        we have to make sure that currently configured connection to database is really used.
        This happens for example in tests, where querysets are initialized as resource classes
        are imported, but then database connection is changed to test database.
        """

        self._meta.queryset._document._collection = None
        self._meta.queryset._collection_obj = self._meta.queryset._document._get_collection(
        )
        if hasattr(self._meta.queryset, '_reset_already_indexed'):
            self._meta.queryset._reset_already_indexed()

    def get_object_list(self, request):
        """
        An ORM-specific implementation of ``get_object_list``.
        Returns a queryset that may have been limited by other overrides.
        """

        self._reset_collection()
        return self._meta.queryset.clone()

    def _get_object_type(self, request):
        match = CONTENT_TYPE_RE.match(request.META.get('CONTENT_TYPE', ''))
        if match:
            return match.group(1)
        elif 'type' in request.GET:
            return request.GET.get('type')
        else:
            return None

    def _wrap_polymorphic(self, resource, fun):
        object_class = self._meta.object_class
        qs = self._meta.queryset
        base_fields = self.base_fields
        fields = self.fields
        try:
            self._meta.object_class = resource._meta.object_class
            self._meta.queryset = resource._meta.queryset
            self.base_fields = resource.base_fields.copy()
            self.fields = resource.fields.copy()
            if getattr(self._meta, 'prefer_polymorphic_resource_uri', False):
                if resource.get_resource_uri():
                    self._meta.resource_name = resource._meta.resource_name
            if getattr(self._meta, 'include_resource_type', True):
                self.base_fields['resource_type'] = base_fields[
                    'resource_type']
                self.fields['resource_type'] = fields['resource_type']
            return fun()
        finally:
            self._meta.object_class = object_class
            self._meta.queryset = qs
            self.base_fields = base_fields
            self.fields = fields

    def _wrap_request(self, request, fun):
        type_map = getattr(self._meta, 'polymorphic', {})
        if not type_map:
            return fun()

        object_type = self._get_object_type(request)
        if not object_type:
            # Polymorphic resources are enabled, but
            # nothing is passed, so set it to a default
            try:
                object_type = self._get_type_from_class(
                    type_map, self._meta.object_class)
            except KeyError:
                raise tastypie_exceptions.BadRequest("Invalid object type.")

        if object_type not in type_map:
            raise tastypie_exceptions.BadRequest("Invalid object type.")

        resource = type_map[object_type](self._meta.api_name)

        # Optimization
        if resource._meta.object_class is self._meta.object_class:
            return fun()

        return self._wrap_polymorphic(resource, fun)

    def dispatch(self, request_type, request, **kwargs):
        # We process specially only requests with payload
        if not request.body:
            assert request.method.lower() not in ('put', 'post',
                                                  'patch'), request.method
            return super(MongoEngineResource,
                         self).dispatch(request_type, request, **kwargs)

        assert request.method.lower() in ('put', 'post',
                                          'patch'), request.method

        return self._wrap_request(
            request, lambda: super(MongoEngineResource, self).dispatch(
                request_type, request, **kwargs))

    def get_schema(self, request, **kwargs):
        return self._wrap_request(
            request, lambda: super(MongoEngineResource, self).get_schema(
                request, **kwargs))

    def _get_resource_from_class(self, type_map, cls):
        for resource in type_map.itervalues():
            if resource._meta.object_class is cls:
                return resource
        raise KeyError(cls)

    def _get_type_from_class(self, type_map, cls):
        # As we are overriding self._meta.object_class we have to make sure
        # that we do not miss real match, so if self._meta.object_class
        # matches, we still check other items, otherwise we return immediately
        res = None
        for typ, resource in type_map.iteritems():
            if resource._meta.object_class is cls:
                if resource._meta.object_class is self._meta.object_class:
                    res = typ
                else:
                    return typ
        if res is not None:
            return res
        else:
            raise KeyError(cls)

    def dehydrate_resource_type(self, bundle):
        type_map = getattr(self._meta, 'polymorphic', {})
        if not type_map:
            return None

        return self._get_type_from_class(type_map, bundle.obj.__class__)

    def full_dehydrate(self, bundle, for_list=False):
        type_map = getattr(self._meta, 'polymorphic', {})
        if not type_map:
            return super(MongoEngineResource,
                         self).full_dehydrate(bundle, for_list)

        # Optimization
        if self._meta.object_class is bundle.obj.__class__:
            return super(MongoEngineResource,
                         self).full_dehydrate(bundle, for_list)

        resource = self._get_resource_from_class(
            type_map, bundle.obj.__class__)(self._meta.api_name)
        return self._wrap_polymorphic(
            resource, lambda: super(MongoEngineResource, self).full_dehydrate(
                bundle, for_list))

    def full_hydrate(self, bundle):
        # When updating objects, we want to force only updates of the same type, and object
        # should be completely replaced if type is changed, so we throw and exception here
        # to direct program logic flow (it is cached and replace instead of update is tried)
        if bundle.obj and self._meta.object_class is not bundle.obj.__class__:
            raise tastypie_exceptions.NotFound(
                "A document instance matching the provided arguments could not be found."
            )

        bundle = super(MongoEngineResource, self).full_hydrate(bundle)

        # We redo check for required fields as Tastypie is not
        # reliable as it does checks in an inconsistent way
        # (https://github.com/toastdriven/django-tastypie/issues/491)
        for field_object in self.fields.itervalues():
            if field_object.readonly or getattr(field_object, '_primary_key',
                                                False):
                continue

            if not field_object.attribute:
                continue

            # Tastypie also skips setting value if it is None, but this means
            # updates to None are ignored: this is not good as it hides invalid
            # PUT/PATCH REST requests (setting value to None which should fail
            # validation (field required) is simply ignored and value is left
            # as it is)
            # (https://github.com/toastdriven/django-tastypie/issues/492)
            # We hydrate field again only if existing value is not None
            if getattr(bundle.obj, field_object.attribute, None) is not None:
                value = NOT_HYDRATED

                # Tastypie also ignores missing fields in PUT,
                # so we check for missing field here
                # (https://github.com/toastdriven/django-tastypie/issues/496)
                if field_object.instance_name not in bundle.data:
                    if field_object.has_default():
                        if callable(field_object.default):
                            value = field_object.default()
                        else:
                            value = field_object.default
                    # If it can be blank, we leave the field as it is, it was possibly already populated or it is not even necessary to be
                    elif field_object.blank:
                        pass
                    else:
                        value = None
                else:
                    value = field_object.hydrate(bundle)
                if value is None:
                    setattr(bundle.obj, field_object.attribute, None)

            if field_object.blank or field_object.null:
                continue

            # We are just trying to fix Tastypie here, for other "null" values
            # like [] and {} we leave to MongoEngine validate to catch them
            if getattr(bundle.obj, field_object.attribute, None) is None:
                raise tastypie_exceptions.ApiFieldError(
                    "The '%s' field has no data and doesn't allow a default or null value."
                    % field_object.instance_name)

        return bundle

    def build_schema(self):
        data = super(MongoEngineResource, self).build_schema()

        for field_name, field_object in self.fields.items():
            # We process ListField specially here (and not use field's
            # build_schema) so that Tastypie's ListField can be used
            if isinstance(field_object, tastypie_fields.ListField):
                if getattr(field_object, 'field', None):
                    data['fields'][field_name]['content'] = {}

                    field_type = field_object.field.__class__.__name__.lower()
                    if field_type.endswith('field'):
                        field_type = field_type[:-5]
                    data['fields'][field_name]['content']['type'] = field_type

                    if field_object.field.__doc__:
                        data['fields'][field_name]['content'][
                            'help_text'] = trim(field_object.field.__doc__)

            if hasattr(field_object, 'build_schema'):
                data['fields'][field_name].update(field_object.build_schema())

        type_map = getattr(self._meta, 'polymorphic', {})
        if not type_map:
            return data

        data.update({
            'resource_types': type_map.keys(),
        })

        return data

    def obj_get(self, bundle, **kwargs):
        # MongoEngine exceptions are separate from Django exceptions, we combine them here
        try:
            return super(MongoEngineResource, self).obj_get(bundle=bundle,
                                                            **kwargs)
        except self._meta.object_class.DoesNotExist, e:
            exp = models_base.subclass_exception(
                'DoesNotExist', (self._meta.object_class.DoesNotExist,
                                 exceptions.ObjectDoesNotExist),
                self._meta.object_class.DoesNotExist.__module__)
            raise exp(*e.args)
        except queryset.DoesNotExist, e:
            exp = models_base.subclass_exception(
                'DoesNotExist',
                (queryset.DoesNotExist, exceptions.ObjectDoesNotExist),
                queryset.DoesNotExist.__module__)
            raise exp(*e.args)
示例#18
0
    def __new__(cls, name, bases, attrs):
        """
        Exactly the same except the line with ``isinstance(b, ROAModelBase)``.
        """
        super_new = super(ModelBase, cls).__new__

        # six.with_metaclass() inserts an extra class called 'NewBase' in the
        # inheritance tree: Model -> NewBase -> object. But the initialization
        # should be executed only once for a given model class.

        # attrs will never be empty for classes declared in the standard way
        # (ie. with the `class` keyword). This is quite robust.
        if name == 'NewBase' and attrs == {}:
            return super_new(cls, name, bases, attrs)

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [b for b in bases if isinstance(b, ROAModelBase) and
                not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))]
        if not parents:
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        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__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if not abstract:
            new_class.add_to_class('DoesNotExist', subclass_exception(str('DoesNotExist'),
                    tuple(x.DoesNotExist
                          for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                    or (ObjectDoesNotExist,),
                    module, attached_to=new_class))
            new_class.add_to_class('MultipleObjectsReturned', subclass_exception(str('MultipleObjectsReturned'),
                    tuple(x.MultipleObjectsReturned
                          for x in parents if hasattr(x, '_meta') and not x._meta.abstract)
                    or (MultipleObjectsReturned,),
                    module, attached_to=new_class))
            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped))

        if getattr(new_class, '_default_manager', None):
            if not is_proxy:
                # Multi-table inheritance doesn't inherit default manager from
                # parents.
                new_class._default_manager = None
                new_class._base_manager = None
            else:
                # Proxy classes do inherit parent's default manager, if none is
                # set explicitly.
                new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
                new_class._base_manager = new_class._base_manager._copy_to_model(new_class)

        # Bail out early if we have already created this class.
        m = get_model(new_class._meta.app_label, name,
                      seed_cache=False, only_installed=False)
        if m is not None:
            return m

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

        # All the fields of any type declared on this model
        new_fields = new_class._meta.local_fields + \
                     new_class._meta.local_many_to_many + \
                     new_class._meta.virtual_fields
        field_names = set([f.name for f in new_fields])

        # Basic setup for proxy models.
        if is_proxy:
            base = None
            for parent in [cls for cls in parents if hasattr(cls, '_meta')]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name)
                    else:
                        continue
                if base is not None:
                    raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
                else:
                    base = parent
            if base is None:
                raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
            if (new_class._meta.local_fields or
                    new_class._meta.local_many_to_many):
                raise FieldError("Proxy model '%s' contains model fields." % name)
            new_class._meta.setup_proxy(base)
            new_class._meta.concrete_model = base._meta.concrete_model
        else:
            new_class._meta.concrete_model = new_class

        # Do the appropriate setup for any model parents.
        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
                if isinstance(f, OneToOneField)])

        for base in parents:
            original_base = base
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                        (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                base = base._meta.concrete_model
                if base in o2o_map:
                    field = o2o_map[base]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(base, name=attr_name,
                            auto_created=True, parent_link=True)
                    new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Proxy models inherit the non-abstract managers from their base,
            # unless they have redefined any of them.
            if is_proxy:
                new_class.copy_managers(original_base._meta.concrete_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '\
                                     'with field of similar name from '\
                                     'abstract base class %r' % \
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        register_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_model(new_class._meta.app_label, name,
                         seed_cache=False, only_installed=False)
        return data

    def obj_get(self, request=None, **kwargs):
        # MongoEngine exceptions are separate from Django exceptions, we combine them here
        try:
            return super(MongoEngineResource, self).obj_get(request, **kwargs)
        except self._meta.object_class.DoesNotExist, e:
            exp = models_base.subclass_exception(
                'DoesNotExist', (self._meta.object_class.DoesNotExist,
                                 exceptions.ObjectDoesNotExist),
                self._meta.object_class.DoesNotExist.__module__)
            raise exp(*e.args)
        except queryset.DoesNotExist, e:
            exp = models_base.subclass_exception(
                'DoesNotExist',
                (queryset.DoesNotExist, exceptions.ObjectDoesNotExist),
                queryset.DoesNotExist.__module__)
            raise exp(*e.args)
        except self._meta.object_class.MultipleObjectsReturned, e:
            exp = models_base.subclass_exception(
                'MultipleObjectsReturned',
                (self._meta.object_class.MultipleObjectsReturned,
                 exceptions.MultipleObjectsReturned),
                self._meta.object_class.MultipleObjectsReturned.__module__)
            raise exp(*e.args)
        except queryset.MultipleObjectsReturned, e:
            exp = models_base.subclass_exception(
                'MultipleObjectsReturned',
                (queryset.MultipleObjectsReturned,
                 exceptions.MultipleObjectsReturned),
                queryset.MultipleObjectsReturned.__module__)
示例#20
0
    def _new_old_django(cls, name, bases, attrs):
        """
        Exactly the same except the line with ``isinstance(b, ROAModelBase)`` and part delimited by 'ROA HACK'
        """
        super_new = super(ModelBase, cls).__new__

        # six.with_metaclass() inserts an extra class called 'NewBase' in the
        # inheritance tree: Model -> NewBase -> object. But the initialization
        # should be executed only once for a given model class.

        # attrs will never be empty for classes declared in the standard way
        # (ie. with the `class` keyword). This is quite robust.
        if name == 'NewBase' and attrs == {}:
            return super_new(cls, name, bases, attrs)

        # Also ensure initialization is only performed for subclasses of Model
        # (excluding Model class itself).
        parents = [
            b for b in bases if isinstance(b, ROAModelBase)
            and not (b.__name__ == 'NewBase' and b.__mro__ == (b, object))
        ]
        if not parents:
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        abstract = getattr(attr_meta, 'abstract', False)
        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__.split('.')[-2]}
        else:
            kwargs = {}

        new_class.add_to_class('_meta', Options(meta, **kwargs))
        if not abstract:
            # ROA HACK:

            subclass_kwargs = {
                'name':
                str('DoesNotExist'),
                'parents':
                tuple(x.DoesNotExist for x in parents
                      if hasattr(x, '_meta') and not x._meta.abstract)
                or (ObjectDoesNotExist, ),
                'module':
                module
            }
            if DJANGO_GT_1_4:
                subclass_kwargs['attached_to'] = new_class

            new_class.add_to_class('DoesNotExist',
                                   subclass_exception(**subclass_kwargs))

            subclass_kwargs = {
                'name':
                str('MultipleObjectsReturned'),
                'parents':
                tuple(x.MultipleObjectsReturned for x in parents
                      if hasattr(x, '_meta') and not x._meta.abstract)
                or (MultipleObjectsReturned, ),
                'module':
                module
            }
            if DJANGO_GT_1_4:
                subclass_kwargs['attached_to'] = new_class

            new_class.add_to_class('MultipleObjectsReturned',
                                   subclass_exception(**subclass_kwargs))

            # END HACK

            if base_meta and not base_meta.abstract:
                # Non-abstract child classes inherit some attributes from their
                # non-abstract parent (unless an ABC comes before it in the
                # method resolution order).
                if not hasattr(meta, 'ordering'):
                    new_class._meta.ordering = base_meta.ordering
                if not hasattr(meta, 'get_latest_by'):
                    new_class._meta.get_latest_by = base_meta.get_latest_by

        is_proxy = new_class._meta.proxy

        # If the model is a proxy, ensure that the base class
        # hasn't been swapped out.
        if is_proxy and base_meta and base_meta.swapped:
            raise TypeError("%s cannot proxy the swapped model '%s'." %
                            (name, base_meta.swapped))

        if getattr(new_class, '_default_manager', None):
            if not is_proxy:
                # Multi-table inheritance doesn't inherit default manager from
                # parents.
                new_class._default_manager = None
                new_class._base_manager = None
            else:
                # Proxy classes do inherit parent's default manager, if none is
                # set explicitly.
                new_class._default_manager = new_class._default_manager._copy_to_model(
                    new_class)
                new_class._base_manager = new_class._base_manager._copy_to_model(
                    new_class)

        # Bail out early if we have already created this class.
        m = get_model(new_class._meta.app_label,
                      name,
                      seed_cache=False,
                      only_installed=False)
        if m is not None:
            return m

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

        # All the fields of any type declared on this model
        new_fields = new_class._meta.local_fields + \
                     new_class._meta.local_many_to_many + \
                     new_class._meta.virtual_fields
        field_names = set([f.name for f in new_fields])

        # Basic setup for proxy models.
        if is_proxy:
            base = None
            for parent in [cls for cls in parents if hasattr(cls, '_meta')]:
                if parent._meta.abstract:
                    if parent._meta.fields:
                        raise TypeError(
                            "Abstract base class containing model fields not permitted for proxy model '%s'."
                            % name)
                    else:
                        continue
                if base is not None:
                    raise TypeError(
                        "Proxy model '%s' has more than one non-abstract model base class."
                        % name)
                else:
                    base = parent
            if base is None:
                raise TypeError(
                    "Proxy model '%s' has no non-abstract model base class." %
                    name)
            if (new_class._meta.local_fields
                    or new_class._meta.local_many_to_many):
                raise FieldError("Proxy model '%s' contains model fields." %
                                 name)
            new_class._meta.setup_proxy(base)
            new_class._meta.concrete_model = base._meta.concrete_model
        else:
            new_class._meta.concrete_model = new_class

        # Do the appropriate setup for any model parents.
        o2o_map = dict([(f.rel.to, f) for f in new_class._meta.local_fields
                        if isinstance(f, OneToOneField)])

        for base in parents:
            original_base = base
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents.
                continue

            parent_fields = base._meta.local_fields + base._meta.local_many_to_many
            # Check for clashes between locally declared fields and those
            # on the base classes (we cannot handle shadowed fields at the
            # moment).
            for field in parent_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                     (field.name, name, base.__name__))
            if not base._meta.abstract:
                # Concrete classes...
                base = base._meta.concrete_model
                if base in o2o_map:
                    field = o2o_map[base]
                elif not is_proxy:
                    attr_name = '%s_ptr' % base._meta.model_name
                    field = OneToOneField(base,
                                          name=attr_name,
                                          auto_created=True,
                                          parent_link=True)
                    new_class.add_to_class(attr_name, field)
                else:
                    field = None
                new_class._meta.parents[base] = field
            else:
                # .. and abstract ones.
                for field in parent_fields:
                    new_class.add_to_class(field.name, copy.deepcopy(field))

                # Pass any non-abstract parent classes onto child.
                new_class._meta.parents.update(base._meta.parents)

            # Inherit managers from the abstract base classes.
            new_class.copy_managers(base._meta.abstract_managers)

            # Proxy models inherit the non-abstract managers from their base,
            # unless they have redefined any of them.
            if is_proxy:
                new_class.copy_managers(original_base._meta.concrete_managers)

            # Inherit virtual fields (like GenericForeignKey) from the parent
            # class
            for field in base._meta.virtual_fields:
                if base._meta.abstract and field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '\
                                     'with field of similar name from '\
                                     'abstract base class %r' % \
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

        if abstract:
            # Abstract base models can't be instantiated and don't appear in
            # the list of models for an app. We do the final setup for them a
            # little differently from normal models.
            attr_meta.abstract = False
            new_class.Meta = attr_meta
            return new_class

        new_class._prepare()
        register_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_model(new_class._meta.app_label,
                         name,
                         seed_cache=False,
                         only_installed=False)
示例#21
0
    def __new__(cls, name, bases, attrs):
        super_new = super(XmlModelBase, cls).__new__
        parents = [b for b in bases if isinstance(b, XmlModelBase)]
        if not parents:
            # If this isn't a subclass of Model, don't do anything special.
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        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__.split('.')[-2]}
        else:
            kwargs = {}

        for attr_name in DEFAULT_NAMES:
            if attr_name == 'app_label':
                continue
            if getattr(meta, attr_name, None) is None:
                for base in parents:
                    if not hasattr(base, '_meta'):
                        continue
                    attr_val = getattr(base._meta, attr_name)
                    if attr_val is not None:
                        kwargs[attr_name] = attr_val
                        break

        new_class.add_to_class('_meta', Options(meta, **kwargs))

        new_class.add_to_class(
            'DoesNotExist',
            subclass_exception(
                'DoesNotExist',
                tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta'))
                or (ObjectDoesNotExist, ), module))
        new_class.add_to_class(
            'MultipleObjectsReturned',
            subclass_exception(
                'MultipleObjectsReturned',
                tuple(x.MultipleObjectsReturned
                      for x in parents if hasattr(x, '_meta'))
                or (MultipleObjectsReturned, ), module))

        # Bail out early if we have already created this class.
        m = get_xml_model(new_class._meta.app_label, name, False)
        if m is not None:
            return m

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

        field_names = set([f.name for f in new_class._meta.local_fields])

        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents
                continue

            for field in base._meta.local_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                     (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

            new_class._meta.parents.update(base._meta.parents)

        new_class._prepare()
        register_xml_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_xml_model(new_class._meta.app_label, name, False)
示例#22
0
def patched_new(cls, name, bases, attrs):
    "Patched version of __new__"

    super_new = super(ModelBase, cls).__new__

    # Also ensure initialization is only performed for subclasses of Model
    # (excluding Model class itself).
    parents = [b for b in bases if isinstance(b, ModelBase)]
    if not parents:
        return super_new(cls, name, bases, attrs)

    # Create the class.
    module = attrs.pop('__module__')
    new_class = super_new(cls, name, bases, {'__module__': module})
    attr_meta = attrs.pop('Meta', None)
    abstract = getattr(attr_meta, 'abstract', False)
    if not attr_meta:
        meta = getattr(new_class, 'Meta', None)
    else:
        meta = attr_meta
    base_meta = getattr(new_class, '_meta', None)

    # Look for an application configuration to attach the model to.
    app_config = apps.get_containing_app_config(module)

    if getattr(meta, 'app_label', None) is None:

        if app_config is None:
            # If the model is imported before the configuration for its
            # application is created (#21719), or isn't in an installed
            # application (#21680), use the legacy logic to figure out the
            # app_label by looking one level up from the package or module
            # named 'models'. If no such package or module exists, fall
            # back to looking one level up from the module this model is
            # defined in.

            # For 'django.contrib.sites.models', this would be 'sites'.
            # For 'geo.models.places' this would be 'geo'.

            if abstract:
                kwargs = {"app_label": None}
            else:
                msg = (
                    "Model class %s.%s doesn't declare an explicit app_label "
                    "and either isn't in an application in INSTALLED_APPS or "
                    "else was imported before its application was loaded. " %
                    (module, name))
                raise RuntimeError(msg)
    else:
        kwargs = {}

    new_class.add_to_class('_meta', Options(meta, **kwargs))
    if not abstract:
        new_class.add_to_class(
            'DoesNotExist',
            subclass_exception(
                str('DoesNotExist'),
                tuple(x.DoesNotExist for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (ObjectDoesNotExist,),
                module,
                attached_to=new_class))
        new_class.add_to_class(
            'MultipleObjectsReturned',
            subclass_exception(
                str('MultipleObjectsReturned'),
                tuple(x.MultipleObjectsReturned for x in parents if hasattr(x, '_meta') and not x._meta.abstract) or (MultipleObjectsReturned,),
                module,
                attached_to=new_class))
        if base_meta and not base_meta.abstract:
            # Non-abstract child classes inherit some attributes from their
            # non-abstract parent (unless an ABC comes before it in the
            # method resolution order).
            if not hasattr(meta, 'ordering'):
                new_class._meta.ordering = base_meta.ordering
            if not hasattr(meta, 'get_latest_by'):
                new_class._meta.get_latest_by = base_meta.get_latest_by

    is_proxy = new_class._meta.proxy

    # If the model is a proxy, ensure that the base class
    # hasn't been swapped out.
    if is_proxy and base_meta and base_meta.swapped:
        raise TypeError("%s cannot proxy the swapped model '%s'." % (name, base_meta.swapped))

    if getattr(new_class, '_default_manager', None):
        if not is_proxy:
            # Multi-table inheritance doesn't inherit default manager from
            # parents.
            new_class._default_manager = None
            new_class._base_manager = None
        else:
            # Proxy classes do inherit parent's default manager, if none is
            # set explicitly.
            new_class._default_manager = new_class._default_manager._copy_to_model(new_class)
            new_class._base_manager = new_class._base_manager._copy_to_model(new_class)

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

    # All the fields of any type declared on this model
    new_fields = (
        new_class._meta.local_fields +
        new_class._meta.local_many_to_many +
        new_class._meta.virtual_fields
    )
    field_names = set(f.name for f in new_fields)

    # Basic setup for proxy models.
    if is_proxy:
        base = None
        for parent in [kls for kls in parents if hasattr(kls, '_meta')]:
            if parent._meta.abstract:
                if parent._meta.fields:
                    raise TypeError("Abstract base class containing model fields not permitted for proxy model '%s'." % name)
                else:
                    continue
            #if base is not None:                              # patch
            while parent._meta.proxy:                          # patch
                parent = parent._meta.proxy_for_model          # patch
            if base is not None and base is not parent:        # patch
                raise TypeError("Proxy model '%s' has more than one non-abstract model base class." % name)
            else:
                base = parent
        if base is None:
            raise TypeError("Proxy model '%s' has no non-abstract model base class." % name)
        new_class._meta.setup_proxy(base)
        new_class._meta.concrete_model = base._meta.concrete_model
    else:
        new_class._meta.concrete_model = new_class

    # Collect the parent links for multi-table inheritance.
    parent_links = {}
    for base in reversed([new_class] + parents):
        # Conceptually equivalent to `if base is Model`.
        if not hasattr(base, '_meta'):
            continue
        # Skip concrete parent classes.
        if base != new_class and not base._meta.abstract:
            continue
        # Locate OneToOneField instances.
        for field in base._meta.local_fields:
            if isinstance(field, OneToOneField):
                parent_links[field.rel.to] = field

    # Do the appropriate setup for any model parents.
    for base in parents:
        original_base = base
        if not hasattr(base, '_meta'):
            # Things without _meta aren't functional models, so they're
            # uninteresting parents.
            continue

        parent_fields = base._meta.local_fields + base._meta.local_many_to_many
        # Check for clashes between locally declared fields and those
        # on the base classes (we cannot handle shadowed fields at the
        # moment).
        for field in parent_fields:
            if field.name in field_names:
                raise FieldError(
                    'Local field %r in class %r clashes '
                    'with field of similar name from '
                    'base class %r' % (field.name, name, base.__name__)
                )
        if not base._meta.abstract:
            # Concrete classes...
            base = base._meta.concrete_model
            if base in parent_links:
                field = parent_links[base]
            elif not is_proxy:
                attr_name = '%s_ptr' % base._meta.model_name
                field = OneToOneField(base, name=attr_name,
                        auto_created=True, parent_link=True)
                # Only add the ptr field if it's not already present;
                # e.g. migrations will already have it specified
                if not hasattr(new_class, attr_name):
                    new_class.add_to_class(attr_name, field)
            else:
                field = None
            new_class._meta.parents[base] = field
        else:
            # .. and abstract ones.
            for field in parent_fields:
                new_class.add_to_class(field.name, copy.deepcopy(field))

            # Pass any non-abstract parent classes onto child.
            new_class._meta.parents.update(base._meta.parents)

        # Inherit managers from the abstract base classes.
        new_class.copy_managers(base._meta.abstract_managers)

        # Proxy models inherit the non-abstract managers from their base,
        # unless they have redefined any of them.
        if is_proxy:
            new_class.copy_managers(original_base._meta.concrete_managers)

        # Inherit virtual fields (like GenericForeignKey) from the parent
        # class
        for field in base._meta.virtual_fields:
            if base._meta.abstract and field.name in field_names:
                raise FieldError(
                    'Local field %r in class %r clashes '
                    'with field of similar name from '
                    'abstract base class %r' % (field.name, name, base.__name__)
                )
            new_class.add_to_class(field.name, copy.deepcopy(field))

    if abstract:
        # Abstract base models can't be instantiated and don't appear in
        # the list of models for an app. We do the final setup for them a
        # little differently from normal models.
        attr_meta.abstract = False
        new_class.Meta = attr_meta
        return new_class

    new_class._prepare()
    new_class._meta.apps.register_model(new_class._meta.app_label, new_class)

    return new_class
示例#23
0
    def __new__(cls, name, bases, attrs):
        super_new = super(XmlModelBase, cls).__new__
        parents = [b for b in bases if isinstance(b, XmlModelBase)]
        if not parents:
            # If this isn't a subclass of Model, don't do anything special.
            return super_new(cls, name, bases, attrs)

        # Create the class.
        module = attrs.pop('__module__')
        new_class = super_new(cls, name, bases, {'__module__': module})
        attr_meta = attrs.pop('Meta', None)
        if not attr_meta:
            meta = getattr(new_class, 'Meta', None)
        else:
            meta = attr_meta

        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__.split('.')[-2]}
        else:
            kwargs = {}

        for attr_name in DEFAULT_NAMES:
            if attr_name == 'app_label':
                continue
            if getattr(meta, attr_name, None) is None:
                for base in parents:
                    if not hasattr(base, '_meta'):
                        continue
                    attr_val = getattr(base._meta, attr_name)
                    if attr_val is not None:
                        kwargs[attr_name] = attr_val
                        break

        new_class.add_to_class('_meta', Options(meta, **kwargs))

        new_class.add_to_class('DoesNotExist', subclass_exception('DoesNotExist',
                tuple(x.DoesNotExist
                        for x in parents if hasattr(x, '_meta'))
                                or (ObjectDoesNotExist,), module))
        new_class.add_to_class('MultipleObjectsReturned', subclass_exception('MultipleObjectsReturned',
                tuple(x.MultipleObjectsReturned
                        for x in parents if hasattr(x, '_meta'))
                                or (MultipleObjectsReturned,), module))

        # Bail out early if we have already created this class.
        m = get_xml_model(new_class._meta.app_label, name, False)
        if m is not None:
            return m

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

        field_names = set([f.name for f in new_class._meta.local_fields])

        for base in parents:
            if not hasattr(base, '_meta'):
                # Things without _meta aren't functional models, so they're
                # uninteresting parents
                continue

            for field in base._meta.local_fields:
                if field.name in field_names:
                    raise FieldError('Local field %r in class %r clashes '
                                     'with field of similar name from '
                                     'base class %r' %
                                        (field.name, name, base.__name__))
                new_class.add_to_class(field.name, copy.deepcopy(field))

            new_class._meta.parents.update(base._meta.parents)

        new_class._prepare()
        register_xml_models(new_class._meta.app_label, new_class)

        # Because of the way imports happen (recursively), we may or may not be
        # the first time this model tries to register with the framework. There
        # should only be one class for each model, so we always return the
        # registered version.
        return get_xml_model(new_class._meta.app_label, name, False)