Esempio n. 1
0
    def data(self):
        links = None
        data = []
        included = []
        included_set = set()

        default_type = type_from_model_name(self.default_model.__name__)
        default_serializer = get_schema(default_type)

        for instance in self.collection:
            type_ = type_from_model_name(instance.__class__.__name__)
            serializer_class = get_schema(type_)
            if not issubclass(serializer_class.opts.model, self.base):
                serializer_class = default_serializer

            serialized = serializer_class(instance=instance,
                                          **self.kwargs).data
            if not links and 'links' in serialized:
                links = serialized['links']
            data.append(serialized['data'])
            for include in serialized.get('included', []):
                key = (include['type'], include['id'])
                if key not in included_set:
                    included.append(include)
                    included_set.add(key)

        response = {'data': data}
        if links:
            response['links'] = links
        if included:
            included.sort(key=itemgetter('type', 'id'))
            response['included'] = included

        return order_dict(response, TOP_LEVEL_OBJECT_ORDER)
Esempio n. 2
0
    def data(self):
        links = None
        data = []
        included = []
        included_set = set()

        default_type = type_from_model_name(self.default_model.__name__)
        default_serializer = get_schema(default_type)

        for instance in self.collection:
            type_ = type_from_model_name(instance.__class__.__name__)
            serializer_class = get_schema(type_)
            if not issubclass(serializer_class.opts.model, self.base):
                serializer_class = default_serializer

            serialized = serializer_class(instance=instance, **self.kwargs).data
            if not links and 'links' in serialized:
                links = serialized['links']
            data.append(serialized['data'])
            for include in serialized.get('included', []):
                key = (include['type'], include['id'])
                if key not in included_set:
                    included.append(include)
                    included_set.add(key)

        response = {
            'data': data
        }
        if links:
            response['links'] = links
        if included:
            included.sort(key=itemgetter('type', 'id'))
            response['included'] = included

        return order_dict(response, TOP_LEVEL_OBJECT_ORDER)
Esempio n. 3
0
    def __new__(cls, base, default_model, instance=None, data=None, many=False,
                **kwargs):
        if not many:
            # in the single instance case return the correct serializer by type
            # or the default_model's serializer if type is not valid for base
            type_ = None
            if instance:
                type_ = type_from_model_name(instance.__class__.__name__)
            elif data:
                type_ = data.get('data', {}).get('type')

            if type_:
                serializer_class = get_schema(type_)
                if not issubclass(serializer_class.opts.model, base):
                    type_ = None

            if not type_:
                type_ = type_from_model_name(default_model.__name__)
                serializer_class = get_schema(type_)

            return serializer_class(
                instance=instance, data=data, many=many, **kwargs)

        if data:
            raise ValueError(
                u"You can only use a JsonApiPolymorphicSerializer with "
                u"many=True for serializing a ModelCollection")

        return super(JsonApiPolymorphicSerializer, cls).__new__(
            cls, base, default_model, instance, data, many, **kwargs)
Esempio n. 4
0
    def _serialize(self, value, attr, obj):
        if not self.many:
            value = [value]

        links = None
        result = []
        if value:
            for instance in value:
                field = Relationship(
                    type_=type_from_model_name(instance.__class__.__name__),
                    id_field='pk',
                    self_url=self.self_url,
                    related_url=self.related_url,
                    many=False)
                field._add_to_schema(self.name, self.parent)
                field.include_data = self.include_data
                data = field._serialize(instance, attr, obj)
                if links is None and 'links' in data:
                    links = data['links']
                result.append(data.get('data'))
        else:
            data = super(PolymorphicRelationship, self)._serialize(
                None, attr, obj)
            if links is None and 'links' in data:
                links = data['links']

        if not self.many:
            result = result[0]
        data = {}
        if links is not None:
            data['links'] = order_dict(links, LINKS_OBJECT_ORDER)
        if self.include_resource_linkage or self.include_data:
            data['data'] = result
        return order_dict(data, TOP_LEVEL_OBJECT_ORDER)
Esempio n. 5
0
    def _serialize(self, value, attr, obj):
        if not self.many:
            value = [value]

        links = None
        result = []
        if value:
            for instance in value:
                field = Relationship(type_=type_from_model_name(
                    instance.__class__.__name__),
                                     id_field='pk',
                                     self_url=self.self_url,
                                     related_url=self.related_url,
                                     many=False)
                field._add_to_schema(self.name, self.parent)
                field.include_data = self.include_data
                data = field._serialize(instance, attr, obj)
                if links is None and 'links' in data:
                    links = data['links']
                result.append(data.get('data'))
        else:
            data = super(PolymorphicRelationship,
                         self)._serialize(None, attr, obj)
            if links is None and 'links' in data:
                links = data['links']

        if not self.many:
            result = result[0]
        data = {}
        if links is not None:
            data['links'] = order_dict(links, LINKS_OBJECT_ORDER)
        if self.include_resource_linkage or self.include_data:
            data['data'] = result
        return order_dict(data, TOP_LEVEL_OBJECT_ORDER)
Esempio n. 6
0
 def add_includes(self, includes):
     included_data = self.included_data
     for instance in includes:
         type_ = type_from_model_name(instance.__class__.__name__)
         serializer = get_schema(type_)(instance,
                                        fields_map=self.fields_map,
                                        exclude_map=self.exclude_map)
         data = serializer.data
         item = data['data']
         included_data[(item['type'], item['id'])] = item
         included_data.update(serializer.included_data)
Esempio n. 7
0
    def format_profile_references(self, instances):
        references = []
        for instance in instances:
            type_ = type_from_model_name(instance.__class__.__name__)
            serializer = get_schema(type_)(instance.with_snapshots(
                ('working', )),
                                           only=('id', ))
            data = serializer.data.get('data', {})
            if data:
                references.append(data)

        return references
Esempio n. 8
0
    def format_profile_references(self, instances):
        references = []
        for instance in instances:
            type_ = type_from_model_name(instance.__class__.__name__)
            serializer = get_schema(type_)(
                instance.with_snapshots(('working',)),
                only=('id',))
            data = serializer.data.get('data', {})
            if data:
                references.append(data)

        return references
Esempio n. 9
0
 def add_includes(self, includes):
     included_data = self.included_data
     for instance in includes:
         type_ = type_from_model_name(instance.__class__.__name__)
         serializer = get_schema(type_)(
             instance,
             fields_map=self.fields_map,
             exclude_map=self.exclude_map)
         data = serializer.data
         item = data['data']
         included_data[(item['type'], item['id'])] = item
         included_data.update(serializer.included_data)
Esempio n. 10
0
    def __new__(cls,
                base,
                default_model,
                instance=None,
                data=None,
                many=False,
                **kwargs):
        if not many:
            # in the single instance case return the correct serializer by type
            # or the default_model's serializer if type is not valid for base
            type_ = None
            if instance:
                type_ = type_from_model_name(instance.__class__.__name__)
            elif data:
                type_ = data.get('data', {}).get('type')

            if type_:
                serializer_class = get_schema(type_)
                if not issubclass(serializer_class.opts.model, base):
                    type_ = None

            if not type_:
                type_ = type_from_model_name(default_model.__name__)
                serializer_class = get_schema(type_)

            return serializer_class(instance=instance,
                                    data=data,
                                    many=many,
                                    **kwargs)

        if data:
            raise ValueError(
                u"You can only use a JsonApiPolymorphicSerializer with "
                u"many=True for serializing a ModelCollection")

        return super(JsonApiPolymorphicSerializer,
                     cls).__new__(cls, base, default_model, instance, data,
                                  many, **kwargs)
Esempio n. 11
0
    def __new__(mcs, name, bases, attrs):
        parents = [b for b in bases if isinstance(b, JsonApiSerializerMeta)]
        if not parents:
            return super(JsonApiSerializerMeta,
                         mcs).__new__(mcs, name, bases, attrs)

        meta = attrs.pop('Meta', None)

        try:
            model = meta.model
        except AttributeError:
            raise TypeError(
                u"Class '{}' is missing the 'Meta.model' attribute.".format(
                    name))

        schema_type = type_from_model_name(model.__name__)

        meta_bases = (meta, object) if meta else (object, )
        schema_attrs = {
            'Meta':
            type('Meta', meta_bases, {
                'type_': schema_type,
                'inflect': dasherize,
            })
        }

        links = getattr(meta, 'links', {})
        for attrname, field in iteritems(model._fields):
            if isinstance(field, OrmField):
                field_copy = object.__new__(field.__class__)
                field_copy.__dict__ = dict(field.__dict__)
                field_copy.load_from = None
                field_copy.dump_to = None
                schema_attrs[attrname] = field_copy
            elif isinstance(field, BaseRelationship):
                rel_links = links.get(attrname, {})
                rel_many = isinstance(field, HasMany)
                rel_options = {
                    'self_url': rel_links.get('self', ''),
                    'related_url': rel_links.get('related', ''),
                    'many': rel_many
                }
                if not rel_many:
                    rel_options['allow_none'] = True
                if field.polymorphic:
                    schema_attrs[attrname] = PolymorphicRelationship(
                        **rel_options)
                else:
                    schema_attrs[attrname] = Relationship(
                        type_=type_from_model_name(field.model.__name__),
                        id_field='pk',
                        serializer=rel_links.get('serializer'),
                        **rel_options)

        if 'id' not in schema_attrs:
            pk_field = model._fields[model._pk_field]
            schema_attrs['id'] = type(pk_field)(attribute=model._pk_field)

        # we need to access the serialized object to generate the url, but
        # get_resource_links takes the serialized item, so we add a method field
        # to do the work
        schema_attrs['_url'] = Method('get_url')

        attrs.update(schema_attrs)
        cls = super(JsonApiSerializerMeta,
                    mcs).__new__(mcs, name, bases, attrs)

        # add new schema to registry by type
        is_custom = name.replace('Serializer', '') != model.__name__
        key = camel_case_to_dashes(name) if is_custom else schema_type
        schemas[key] = cls
        return cls
Esempio n. 12
0
    def __new__(mcs, name, bases, attrs):
        parents = [b for b in bases if isinstance(b, JsonApiSerializerMeta)]
        if not parents:
            return super(JsonApiSerializerMeta, mcs).__new__(
                mcs, name, bases, attrs)

        meta = attrs.pop('Meta', None)

        try:
            model = meta.model
        except AttributeError:
            raise TypeError(
                u"Class '{}' is missing the 'Meta.model' attribute.".format(
                    name))

        schema_type = type_from_model_name(model.__name__)

        meta_bases = (meta, object) if meta else (object,)
        schema_attrs = {
            'Meta': type('Meta', meta_bases, {
                'type_': schema_type,
                'inflect': dasherize,
            })
        }

        links = getattr(meta, 'links', {})
        for attrname, field in iteritems(model._fields):
            if isinstance(field, OrmField):
                field_copy = object.__new__(field.__class__)
                field_copy.__dict__ = dict(field.__dict__)
                field_copy.load_from = None
                field_copy.dump_to = None
                schema_attrs[attrname] = field_copy
            elif isinstance(field, BaseRelationship):
                rel_links = links.get(attrname, {})
                rel_many = isinstance(field, HasMany)
                rel_options = {
                    'self_url': rel_links.get('self', ''),
                    'related_url': rel_links.get('related', ''),
                    'many': rel_many
                }
                if not rel_many:
                    rel_options['allow_none'] = True
                if field.polymorphic:
                    schema_attrs[attrname] = PolymorphicRelationship(
                        **rel_options)
                else:
                    schema_attrs[attrname] = Relationship(
                        type_=type_from_model_name(field.model.__name__),
                        id_field='pk',
                        serializer=rel_links.get('serializer'),
                        **rel_options)

        if 'id' not in schema_attrs:
            pk_field = model._fields[model._pk_field]
            schema_attrs['id'] = type(pk_field)(attribute=model._pk_field)

        # we need to access the serialized object to generate the url, but
        # get_resource_links takes the serialized item, so we add a method field
        # to do the work
        schema_attrs['_url'] = Method('get_url')

        attrs.update(schema_attrs)
        cls = super(JsonApiSerializerMeta, mcs).__new__(mcs, name, bases, attrs)

        # add new schema to registry by type
        is_custom = name.replace('Serializer', '') != model.__name__
        key = camel_case_to_dashes(name) if is_custom else schema_type
        schemas[key] = cls
        return cls