コード例 #1
0
ファイル: options.py プロジェクト: yashasaxena/lecture22
    def add_field(self, field_inst):
        """Add or replace a given Field."""
        try:
            orig_field = self.get_field(field_inst.mongo_name)
        except Exception:
            # FieldDoesNotExist, etc. may be raised by subclasses.
            orig_field = None
        if orig_field is None:
            try:
                orig_field = self.get_field_from_attname(field_inst.attname)
            except Exception:
                pass

        if orig_field:
            if field_inst.attname != orig_field.attname:
                raise InvalidModel('%r cannot have the same mongo_name of '
                                   'existing field %r' % (field_inst.attname,
                                                          orig_field.attname))
            # Remove the field as it may have a different MongoDB name.
            del self.fields_dict[orig_field.mongo_name]
            self.fields_ordered.remove(orig_field)

        self.fields_dict[field_inst.mongo_name] = field_inst
        self.fields_attname_dict[field_inst.attname] = field_inst
        index = bisect(self.fields_ordered, field_inst)
        self.fields_ordered.insert(index, field_inst)

        # Set the primary key if we don't have one yet, or it if is implicit.
        if field_inst.primary_key and self.pk is None or self.implicit_id:
            self.pk = field_inst
コード例 #2
0
ファイル: models.py プロジェクト: vitaliy-grusha/pymodm
    def __new__(mcls, name, bases, attrs):
        model_parents = [
            base for base in bases if isinstance(base, MongoModelMetaclass)
        ]
        # Only perform Model initialization steps if the class has inherited
        # from a Model base class (i.e. MongoModel/EmbeddedMongoModel).
        if not model_parents:
            return type.__new__(mcls, name, bases, attrs)

        new_attrs = {'__module__': attrs['__module__']}
        if '__classcell__' in attrs:
            new_attrs['__classcell__'] = attrs['__classcell__']
        new_class = type.__new__(mcls, name, bases, new_attrs)

        # User-defined or inherited metadata
        meta = attrs.get('Meta', getattr(new_class, 'Meta', None))
        # Allow the options class to be pluggable.
        # Pop it from attrs, since it's not useful in the final class.
        options_class = attrs.pop('_options_class', MongoOptions)
        options = options_class(meta)

        # Let the Options object take care of merging relevant options.
        new_class.add_to_class('_mongometa', options)

        # Add all attributes to class.
        for attr in attrs:
            new_class.add_to_class(attr, attrs[attr])

        def should_inherit_field(parent_class, field):
            # Never shadow fields defined on the new class.
            if field.attname in new_class._mongometa.fields_attname_dict:
                return False
            # Never inherit an implicit primary key.
            if field.primary_key and parent_class._mongometa.implicit_id:
                return False
            return True

        # Also add fields from parents into the metadata.
        for base in model_parents:
            if hasattr(base, '_mongometa'):
                parent_fields = base._mongometa.get_fields()
                for field in parent_fields:
                    if should_inherit_field(base, field):
                        new_class.add_to_class(field.attname, field)

        # Discover and store class hierarchy for later.
        class_name = new_class._mongometa.object_name
        new_class._subclasses = set([class_name])
        flattened_bases = new_class._get_bases(bases)
        for base in flattened_bases:
            if base._mongometa.final:
                raise InvalidModel('Cannot extend class %s, '
                                   'because it has been declared final.' %
                                   base._mongometa.object_name)
            base._subclasses.add(class_name)

        # Set the default collection name.
        if new_class._mongometa.collection_name is None:
            # If this class extends another custom MongoModel, use the same
            # collection.
            if flattened_bases:
                parent_cls = next(iter(flattened_bases))
                parent_collection_name = parent_cls._mongometa.collection_name
                new_class._mongometa.collection_name = parent_collection_name
            else:
                new_class._mongometa.collection_name = snake_case(name)

        # Create model-specific Exception types.
        for exc_type in (errors.DoesNotExist, errors.MultipleObjectsReturned):
            exc_name = exc_type.__name__
            parent_types = tuple(
                getattr(base, exc_name) for base in bases
                if hasattr(base, exc_name))
            model_exc = type(exc_name, parent_types or (exc_type, ),
                             {'__module__': attrs['__module__']})
            new_class.add_to_class(exc_name, model_exc)

        # Add class to the registry.
        register_document(new_class)

        return new_class