@staticmethod
    def extract_relationships(fields, resource, resource_instance):
        # Avoid circular deps
        from rest_framework_json_api.relations import ResourceRelatedField

        data = OrderedDict()

        # Don't try to extract relationships from a non-existent resource
        if resource_instance is None:
            return

        for field_name, field in six.iteritems(fields):
            # Skip URL field
            if field_name == api_settings.URL_FIELD_NAME:
                continue

            # Skip fields without relations
            if not isinstance(field, (relations.RelatedField, relations.ManyRelatedField, BaseSerializer)):
                continue

            source = field.source
            try:
                relation_instance_or_manager = getattr(resource_instance, source)
            except __HOLE__:
                # if the field is not defined on the model then we check the serializer
                # and if no value is there we skip over the field completely
                serializer_method = getattr(field.parent, source, None)
                if serializer_method and hasattr(serializer_method, '__call__'):
                    relation_instance_or_manager = serializer_method(resource_instance)
                else:
                    continue

            relation_type = utils.get_related_resource_type(field)

            if isinstance(field, relations.HyperlinkedIdentityField):
                # special case for HyperlinkedIdentityField
                relation_data = list()

                # Don't try to query an empty relation
                relation_queryset = relation_instance_or_manager.all() \
                    if relation_instance_or_manager is not None else list()

                for related_object in relation_queryset:
                    relation_data.append(
                        OrderedDict([('type', relation_type), ('id', encoding.force_text(related_object.pk))])
                    )

                data.update({field_name: {
                    'links': {
                        "related": resource.get(field_name)},
                    'data': relation_data,
                    'meta': {
                        'count': len(relation_data)
                    }
                }})
                continue

            if isinstance(field, ResourceRelatedField):
                # special case for ResourceRelatedField
                relation_data = {
                    'data': resource.get(field_name)
                }

                field_links = field.get_links(resource_instance)
                relation_data.update(
                    {'links': field_links}
                    if field_links else dict()
                )
                data.update({field_name: relation_data})
                continue

            if isinstance(field, (relations.PrimaryKeyRelatedField, relations.HyperlinkedRelatedField)):
                relation_id = relation_instance_or_manager.pk if resource.get(field_name) else None

                relation_data = {
                    'data': (
                        OrderedDict([('type', relation_type), ('id', encoding.force_text(relation_id))])
                        if relation_id is not None else None)
                }

                relation_data.update(
                    {'links': {'related': resource.get(field_name)}}
                    if isinstance(field, relations.HyperlinkedRelatedField) and resource.get(field_name) else dict()
                )
                data.update({field_name: relation_data})
                continue

            if isinstance(field, relations.ManyRelatedField):

                if isinstance(field.child_relation, ResourceRelatedField):
                    # special case for ResourceRelatedField
                    relation_data = {
                        'data': resource.get(field_name)
                    }

                    field_links = field.child_relation.get_links(resource_instance)
                    relation_data.update(
                        {'links': field_links}
                        if field_links else dict()
                    )
                    relation_data.update(
                        {
                            'meta': {
                                'count': len(resource.get(field_name))
                            }
                        }
                    )
                    data.update({field_name: relation_data})
                    continue

                relation_data = list()
                for related_object in relation_instance_or_manager.all():
                    related_object_type = utils.get_instance_or_manager_resource_type(related_object)
                    relation_data.append(OrderedDict([
                        ('type', related_object_type),
                        ('id', encoding.force_text(related_object.pk))
                    ]))
                data.update({
                    field_name: {
                        'data': relation_data,
                        'meta': {
                            'count': len(relation_data)
                        }
                    }
                })
                continue

            if isinstance(field, ListSerializer):
                relation_data = list()

                serializer_data = resource.get(field_name)
                resource_instance_queryset = list(relation_instance_or_manager.all())
                if isinstance(serializer_data, list):
                    for position in range(len(serializer_data)):
                        nested_resource_instance = resource_instance_queryset[position]
                        nested_resource_instance_type = utils.get_resource_type_from_instance(nested_resource_instance)
                        relation_data.append(OrderedDict([
                            ('type', nested_resource_instance_type),
                            ('id', encoding.force_text(nested_resource_instance.pk))
                        ]))

                    data.update({field_name: {'data': relation_data}})
                    continue

            if isinstance(field, ModelSerializer):
                relation_model = field.Meta.model
                relation_type = utils.format_type(relation_model.__name__)

                data.update({
                    field_name: {
                        'data': (
                            OrderedDict([
                                ('type', relation_type),
                                ('id', encoding.force_text(relation_instance_or_manager.pk))
                            ]) if resource.get(field_name) else None)
                    }
                })
                continue

        return utils.format_keys(data)
dataset/ETHPy150Open django-json-api/django-rest-framework-json-api/rest_framework_json_api/renderers.py/JSONRenderer.extract_relationships