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)
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)
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)
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)
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)
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)
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
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
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)
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)
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
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