@staticmethod
    def extract_included(fields, resource, resource_instance, included_resources):
        # this function may be called with an empty record (example: Browsable Interface)
        if not resource_instance:
            return

        included_data = list()
        current_serializer = fields.serializer
        context = current_serializer.context
        included_serializers = utils.get_included_serializers(current_serializer)
        included_resources = copy.copy(included_resources)

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

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

            try:
                included_resources.remove(field_name)
            except ValueError:
                # Skip fields not in requested included resources
                # If no child field, directly continue with the next field
                if field_name not in [node.split('.')[0] for node in included_resources]:
                    continue

            try:
                relation_instance_or_manager = getattr(resource_instance, field_name)
            except AttributeError:
                try:
                    # For ManyRelatedFields if `related_name` is not set we need to access `foo_set` from `source`
                    relation_instance_or_manager = getattr(resource_instance, field.child_relation.source)
                except AttributeError:
                    if not hasattr(current_serializer, field.source):
                        continue
                    serializer_method = getattr(current_serializer, field.source)
                    relation_instance_or_manager = serializer_method(resource_instance)

            new_included_resources = [key.replace('%s.' % field_name, '', 1)
                                      for key in included_resources
                                      if field_name == key.split('.')[0]]
            serializer_data = resource.get(field_name)

            if isinstance(field, relations.ManyRelatedField):
                serializer_class = included_serializers.get(field_name)
                field = serializer_class(relation_instance_or_manager.all(), many=True, context=context)
                serializer_data = field.data

            if isinstance(field, relations.RelatedField):
                serializer_class = included_serializers.get(field_name)
                if relation_instance_or_manager is None:
                    continue
                field = serializer_class(relation_instance_or_manager, context=context)
                serializer_data = field.data

            if isinstance(field, ListSerializer):
                serializer = field.child
                relation_type = utils.get_resource_type_from_serializer(serializer)
                relation_queryset = list(relation_instance_or_manager.all())

                # Get the serializer fields
                serializer_fields = utils.get_serializer_fields(serializer)
                if serializer_data:
                    for position in range(len(serializer_data)):
                        serializer_resource = serializer_data[position]
                        nested_resource_instance = relation_queryset[position]
                        included_data.append(
                            JSONRenderer.build_json_resource_obj(
                                serializer_fields, serializer_resource, nested_resource_instance, relation_type
                            )
                        )
                        included_data.extend(
                            JSONRenderer.extract_included(
                                serializer_fields, serializer_resource, nested_resource_instance, new_included_resources
                            )
                        )

            if isinstance(field, ModelSerializer):

                relation_type = utils.get_resource_type_from_serializer(field)

                # Get the serializer fields
                serializer_fields = utils.get_serializer_fields(field)
                if serializer_data:
                    included_data.append(
                        JSONRenderer.build_json_resource_obj(
                            serializer_fields, serializer_data,
                            relation_instance_or_manager, relation_type)
                    )
                    included_data.extend(
                        JSONRenderer.extract_included(
                            serializer_fields, serializer_data, relation_instance_or_manager, new_included_resources
                        )
                    )

        return utils.format_keys(included_data)
dataset/ETHPy150Open django-json-api/django-rest-framework-json-api/rest_framework_json_api/renderers.py/JSONRenderer.extract_included/original