Example #1
0
def get_consumes(parser_classes):
    """Extract ``consumes`` MIME types from a list of parser classes.

    :param list parser_classes: parser classes
    :return: MIME types for ``consumes``
    :rtype: list[str]
    """
    media_types = [parser.media_type for parser in parser_classes or []]
    if all(is_form_media_type(encoding) for encoding in media_types):
        return media_types
    else:
        media_types = [
            encoding for encoding in media_types
            if not is_form_media_type(encoding)
        ]
        return media_types
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, 'serializer', None)
        if serializer and not getattr(serializer, 'many', False):
            instance = getattr(serializer, 'instance', None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        # If this is valid serializer data, and the form is for the same
        # HTTP method as was used in the request then use the existing
        # serializer instance, rather than dynamically creating a new one.
        if request.method == method and serializer is not None:
            try:
                data = request.data
            except ParseError:
                data = None
            existing_serializer = serializer
        else:
            data = None
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (
                not getattr(view, 'get_serializer', None)
                or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
            ):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance, data=data)
                else:
                    serializer = view.get_serializer(data=data)
                if data is not None:
                    serializer.is_valid()
            form_renderer = self.form_renderer_class()
            return form_renderer.render(
                serializer.data,
                self.accepted_media_type,
                dict(
                    list(self.renderer_context.items()) +
                    [('template', 'rest_framework/api_form.html')]
                )
            )
    def get_rendered_html_form(self, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        if request.method == method:
            data = request.DATA
            files = request.FILES
        else:
            data = None
            files = None

        with override_method(view, request, method) as request:
            obj = getattr(view, 'object', None)
            if not self.show_form_for_method(view, method, request, obj):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (not getattr(view, 'get_serializer', None)
                or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)):
                return

            serializer = view.get_serializer(instance=obj, data=data, files=files)
            serializer.is_valid()
            data = serializer.data

            form_renderer = self.form_renderer_class()
            return form_renderer.render(data, self.accepted_media_type, self.renderer_context)
    def get_rendered_html_form(self, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        with override_method(view, request, method) as request:
            obj = getattr(view, 'object', None)
            if not self.show_form_for_method(view, method, request, obj):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (not getattr(view, 'get_serializer', None) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes)):
                return

            serializer = view.get_serializer(instance=obj)

            data = serializer.data
            form_renderer = self.form_renderer_class()
            return form_renderer.render(data, self.accepted_media_type,
                                        self.renderer_context)
Example #5
0
    def get_default_responses(self):
        """Get the default responses determined for this view from the request serializer and request method.

        :type: dict[str, openapi.Schema]
        """
        method = self.method.lower()

        default_status = guess_response_status(method)
        default_schema = ''
        if method in ('get', 'post', 'put', 'patch'):
            default_schema = self.get_request_serializer(
            ) or self.get_view_serializer()

        default_schema = default_schema or ''
        if any(
                is_form_media_type(encoding)
                for encoding in self.get_consumes()):
            default_schema = ''
        if default_schema and not isinstance(default_schema, openapi.Schema):
            default_schema = self.serializer_to_schema(default_schema) or ''

        if default_schema:
            if is_list_view(self.path, self.method,
                            self.view) and self.method.lower() == 'get':
                default_schema = openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=default_schema)
            if self.should_page():
                default_schema = self.get_paginated_response(
                    default_schema) or default_schema

        return OrderedDict({str(default_status): default_schema})
Example #6
0
    def __init__(self, view, request, request_data=None, files=None):
        """
        May raise ValidationError when checking is False when accessing parameters
        """
        self._opts = view._meta
        self._request = request
        is_form = True
        if request.method == 'POST':
            meta = request.META
            content_type = meta.get('CONTENT_TYPE',
                                    meta.get('HTTP_CONTENT_TYPE', ''))
            is_form = is_form_media_type(content_type)
        self._bounded_form = view.param_form(data=request_data,
                                             files=files,
                                             is_form=is_form)
        self._dependency = self._opts.param_dependency
        if self._opts.param_managed:
            errors = self._bounded_form.errors
            if errors:
                raise ValidationError(errors)

            self._cleaned_data = self._bounded_form.cleaned_data

            self._clean_dependency()
        else:
            self._cleaned_data = {}
Example #7
0
    def get_default_responses(self):
        """Get the default responses determined for this view from the request serializer and request method.

        :type: dict[str, openapi.Schema]
        """
        method = self.method.lower()

        default_status = status.HTTP_200_OK
        default_schema = ''
        if method == 'post':
            default_status = status.HTTP_201_CREATED
            default_schema = self.get_request_serializer(
            ) or self.get_view_serializer()
        elif method == 'delete':
            default_status = status.HTTP_204_NO_CONTENT
        elif method in ('get', 'put', 'patch'):
            default_schema = self.get_request_serializer(
            ) or self.get_view_serializer()

        default_schema = default_schema or ''
        if any(
                is_form_media_type(encoding)
                for encoding in self.get_consumes()):
            default_schema = ''
        if default_schema:
            if not isinstance(default_schema, openapi.Schema):
                default_schema = self.serializer_to_schema(default_schema)
            if is_list_view(self.path, self.method,
                            self.view) and self.method.lower() == 'get':
                default_schema = openapi.Schema(type=openapi.TYPE_ARRAY,
                                                items=default_schema)
            if self.should_page():
                default_schema = self.get_paged_response_schema(default_schema)

        return {str(default_status): default_schema}
Example #8
0
    def add_manual_parameters(self, parameters):
        """Add/replace parameters from the given list of automatically generated request parameters.

        :param list[openapi.Parameter] parameters: genereated parameters
        :return: modified parameters
        :rtype: list[openapi.Parameter]
        """
        manual_parameters = self.overrides.get('manual_parameters', None) or []

        if any(param.in_ == openapi.IN_BODY
               for param in manual_parameters):  # pragma: no cover
            raise SwaggerGenerationError(
                "specify the body parameter as a Schema or Serializer in request_body"
            )
        if any(param.in_ == openapi.IN_FORM
               for param in manual_parameters):  # pragma: no cover
            has_body_parameter = any(param.in_ == openapi.IN_BODY
                                     for param in parameters)
            if has_body_parameter or not any(
                    is_form_media_type(encoding)
                    for encoding in self.get_consumes()):
                raise SwaggerGenerationError(
                    "cannot add form parameters when the request has a request body; "
                    "did you forget to set an appropriate parser class on the view?"
                )
            if self.method not in self.body_methods:
                raise SwaggerGenerationError(
                    "form parameters can only be applied to "
                    "(" + ','.join(self.body_methods) + ") HTTP methods")

        return merge_params(parameters, manual_parameters)
Example #9
0
def get_consumes(parser_classes):
    """Extract ``consumes`` MIME types from a list of parser classes.

    :param list parser_classes: parser classes
    :type parser_classes: list[rest_framework.parsers.BaseParser or type[rest_framework.parsers.BaseParser]]
    :return: MIME types for ``consumes``
    :rtype: list[str]
    """
    parser_classes = get_object_classes(parser_classes)
    parser_classes = [
        pc for pc in parser_classes if not issubclass(pc, FileUploadParser)
    ]
    media_types = [parser.media_type for parser in parser_classes or []]
    non_form_media_types = [
        encoding for encoding in media_types
        if not is_form_media_type(encoding)
    ]
    # Because swagger Parameter objects don't support complex data types (nested objects, arrays),
    # we can't use those unless we are sure the view *only* accepts form data
    # This means that a view won't support file upload in swagger unless it explicitly
    # sets its parser classes to include only form parsers
    if len(non_form_media_types) == 0:
        return media_types

    # If the form accepts both form data and another type, like json (which is the default config),
    # we will render its input as a Schema and thus it file parameters will be read-only
    return non_form_media_types
Example #10
0
    def get_request_body_parameters(self, consumes):
        """Return the request body parameters for this view. |br|
        This is either:

        -  a list with a single object Parameter with a :class:`.Schema` derived from the request serializer
        -  a list of primitive Parameters parsed as form data

        :param list[str] consumes: a list of accepted MIME types as returned by :meth:`.get_consumes`
        :return: a (potentially empty) list of :class:`.Parameter`\\ s either ``in: body`` or ``in: formData``
        :rtype: list[openapi.Parameter]
        """
        serializer = self.get_request_serializer()
        schema = None
        if serializer is None:
            return []

        if isinstance(serializer, openapi.Schema.OR_REF):
            schema = serializer

        if any(is_form_media_type(encoding) for encoding in consumes):
            if schema is not None:
                raise SwaggerGenerationError(
                    "form request body cannot be a Schema")
            return self.get_request_form_parameters(serializer)
        else:
            if schema is None:
                schema = self.get_request_body_schema(serializer)
            return [self.make_body_parameter(schema)
                    ] if schema is not None else []
Example #11
0
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, 'serializer', None)
        if serializer and not getattr(serializer, 'many', False):
            instance = getattr(serializer, 'instance', None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        # If this is valid serializer data, and the form is for the same
        # HTTP method as was used in the request then use the existing
        # serializer instance, rather than dynamically creating a new one.
        if request.method == method and serializer is not None:
            try:
                kwargs = {'data': request.data}
            except ParseError:
                kwargs = {}
            existing_serializer = serializer
        else:
            kwargs = {}
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (not getattr(view, 'get_serializer', None) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes)):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance,
                                                     **kwargs)
                else:
                    serializer = view.get_serializer(**kwargs)

            if hasattr(serializer, 'initial_data'):
                serializer.is_valid()

            form_renderer = self.form_renderer_class()
            return form_renderer.render(
                serializer.data, self.accepted_media_type,
                dict(
                    list(self.renderer_context.items()) +
                    [('template', 'rest_framework/api_form.html')]))
Example #12
0
    def get_rendered_html_form(self, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        if request.method == method:
            try:
                data = request.DATA
                files = request.FILES
            except ParseError:
                data = None
                files = None
        else:
            data = None
            files = None

        with override_method(view, request, method) as request:
            obj = getattr(view, 'object', None)
            if not self.show_form_for_method(view, method, request, obj):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (not getattr(view, 'get_serializer', None) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes)):
                return
            # try loading the partial data
            serializer = view.get_serializer(instance=obj,
                                             data=data,
                                             files=files)
            data_complete = serializer.is_valid()
            data = serializer.data
            if not data_complete:
                for k, f in serializer.fields.iteritems():
                    if k in data and k in request.GET:
                        try:
                            if type(data[k]) == list:
                                x = list()
                                for i in request.GET.getlist(k):
                                    try:
                                        x.append(f.from_native(i).id)
                                    except:
                                        pass
                            else:
                                x = f.from_native(request.GET.get(k))
                            data[k] = x
                            data.fields[k]._value = x
                        except Exception:
                            pass
            form_renderer = self.form_renderer_class()
            return form_renderer.render(data, self.accepted_media_type,
                                        self.renderer_context)
Example #13
0
    def get_rendered_html_form(self, data, view, method, request):
        old_serializer = getattr(data, 'serializer', None)
        if old_serializer and not getattr(old_serializer, 'many', False):
            instance = getattr(old_serializer, 'instance', None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        if request.method == method and old_serializer is not None:
            try:
                kwargs = {'data': request.data}
            except ParseError:
                kwargs = {}
        else:
            kwargs = {}

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            has_serializer = getattr(view, 'get_serializer', None)

            if ((not has_serializer) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes)):
                return

            if has_serializer:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance,
                                                     method=method,
                                                     **kwargs)
                else:
                    try:
                        serializer = view.get_serializer(method=method,
                                                         **kwargs)
                    except TypeError:
                        serializer = view.get_serializer(**kwargs)
            else:
                # at this point we must have a serializer_class
                if method in ('PUT', 'PATCH'):
                    serializer = self._get_serializer(view.serializer_class,
                                                      view,
                                                      request,
                                                      instance=instance,
                                                      **kwargs)
                else:
                    serializer = self._get_serializer(view.serializer_class,
                                                      view, request, **kwargs)

            return self.render_form_for_serializer(serializer)
Example #14
0
    def get_consumes(self):
        """Return the MIME types this endpoint can consume.

        :rtype: list[str]
        """
        media_types = [
            parser.media_type
            for parser in getattr(self.view, 'parser_classes', [])
        ]
        if all(is_form_media_type(encoding) for encoding in media_types):
            return media_types
        return media_types[:1]
Example #15
0
    def get_rendered_html_form(self, data, view, method, request):
        old_serializer = getattr(data, 'serializer', None)
        if old_serializer and not getattr(old_serializer, 'many', False):
            instance = getattr(old_serializer, 'instance', None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        if request.method == method and old_serializer is not None:
            try:
                kwargs = {'data': request.data}
            except ParseError:
                kwargs = {}
        else:
            kwargs = {}

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            has_serializer = getattr(view, 'get_serializer', None)

            if (
                (not has_serializer) or
                not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
            ):
                return

            if has_serializer:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance, method=method, **kwargs)
                else:
                    try:
                        serializer = view.get_serializer(method=method, **kwargs)
                    except TypeError:
                        serializer = view.get_serializer(**kwargs)
            else:
                # at this point we must have a serializer_class
                if method in ('PUT', 'PATCH'):
                    serializer = self._get_serializer(view.serializer_class, view,
                                                      request, instance=instance, **kwargs)
                else:
                    serializer = self._get_serializer(view.serializer_class, view,
                                                      request, **kwargs)

            return self.render_form_for_serializer(serializer)
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, 'serializer', None)
        if serializer and not getattr(serializer, 'many', False):
            instance = getattr(serializer, 'instance', None)
        else:
            instance = None

        if request.method == method:
            try:
                data = request.data
            except ParseError:
                data = None
            existing_serializer = serializer
        else:
            data = None
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (not getattr(view, 'get_serializer', None) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes)):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance,
                                                     data=data)
                else:
                    serializer = view.get_serializer(data=data)
                if data is not None:
                    serializer.is_valid()
            form_renderer = self.form_renderer_class()
            return form_renderer.render(serializer.data,
                                        self.accepted_media_type,
                                        self.renderer_context)
Example #17
0
def get_consumes(parser_classes):
    """Extract ``consumes`` MIME types from a list of parser classes.

    :param list parser_classes: parser classes
    :type parser_classes: list[rest_framework.parsers.BaseParser or type[rest_framework.parsers.BaseParser]]
    :return: MIME types for ``consumes``
    :rtype: list[str]
    """
    parser_classes = get_object_classes(parser_classes)
    media_types = [parser.media_type for parser in parser_classes or []]
    non_form_media_types = [encoding for encoding in media_types if not is_form_media_type(encoding)]
    if len(non_form_media_types) == 0:
        return media_types
    else:
        return non_form_media_types
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, 'serializer', None)
        if serializer and not getattr(serializer, 'many', False):
            instance = getattr(serializer, 'instance', None)
        else:
            instance = None

        if request.method == method:
            try:
                data = request.data
            except ParseError:
                data = None
            existing_serializer = serializer
        else:
            data = None
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            if (
                not getattr(view, 'get_serializer', None)
                or not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
            ):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if method in ('PUT', 'PATCH'):
                    serializer = view.get_serializer(instance=instance, data=data)
                else:
                    serializer = view.get_serializer(data=data)
                if data is not None:
                    serializer.is_valid()
            form_renderer = self.form_renderer_class()
            return form_renderer.render(serializer.data, self.accepted_media_type, self.renderer_context)
Example #19
0
    def __call__(self, request):
        assert isinstance(request, HttpRequest)

        # Parse body with underlying Django request
        request.body

        # Process request with DRF view
        response = self.get_response(request)

        # Ensure request.POST is set as appropriate
        if is_form_media_type(request.content_type):
            assert request.POST == {'foo': ['bar']}
        else:
            assert request.POST == {}

        return response
    def __call__(self, request):
        assert isinstance(request, HttpRequest)

        # Parse body with underlying Django request
        request.body

        # Process request with DRF view
        response = self.get_response(request)

        # Ensure request.POST is set as appropriate
        if is_form_media_type(request.content_type):
            assert request.POST == {'foo': ['bar']}
        else:
            assert request.POST == {}

        return response
Example #21
0
    def add_manual_parameters(self, parameters):
        """Add/replace parameters from the given list of automatically generated request parameters.

        :param list[openapi.Parameter] parameters: genereated parameters
        :return: modified parameters
        :rtype: list[openapi.Parameter]
        """
        manual_parameters = self.overrides.get("manual_parameters", None) or []
        auto_include_parameters = self.overrides.get("auto_include_parameters",
                                                     True)

        body_schema_at_wrong_place = any(param.in_ == openapi.IN_BODY
                                         for param in manual_parameters)
        if body_schema_at_wrong_place:  # pragma: no cover
            raise SwaggerGenerationError(
                "specify the body parameter as a Schema or Serializer in request_body"
            )

        has_manual_form_parameter = any(param.in_ == openapi.IN_FORM
                                        for param in manual_parameters)
        if has_manual_form_parameter:  # pragma: no cover
            has_body_parameter = any(param.in_ == openapi.IN_BODY
                                     for param in parameters)
            has_correct_consumes = any(
                is_form_media_type(encoding)
                for encoding in self.get_consumes())

            # A manual form parameter is invalid when
            # 1. The parent operation accepts body parameter
            # 2. The parent operation does not consume form data or multipart form data
            has_invalid_parameter = auto_include_parameters and (
                has_body_parameter or not has_correct_consumes)
            if has_invalid_parameter:

                raise SwaggerGenerationError(
                    "cannot add form parameters when the request has a request body; "
                    "did you forget to set an appropriate parser class on the view?"
                )
            if self.method not in self.body_methods:
                raise SwaggerGenerationError(
                    "form parameters can only be applied to "
                    "(" + ",".join(self.body_methods) + ") HTTP methods")

        return (merge_params(parameters, manual_parameters)
                if auto_include_parameters else manual_parameters)
Example #22
0
def get_consumes(parser_classes):
    """Extract ``consumes`` MIME types from a list of parser classes.

    :param list parser_classes: parser classes
    :type parser_classes: list[rest_framework.parsers.BaseParser or type[rest_framework.parsers.BaseParser]]
    :return: MIME types for ``consumes``
    :rtype: list[str]
    """
    parser_classes = get_object_classes(parser_classes)
    parser_classes = [pc for pc in parser_classes if not issubclass(pc, FileUploadParser)]
    media_types = [parser.media_type for parser in parser_classes or []]
    non_form_media_types = [encoding for encoding in media_types if not is_form_media_type(encoding)]
    # Because some data to parse could be nested array and are not supported by form media type like multipart/form-data,
    # we must be sure to have explicit form media types **only**.
    if len(non_form_media_types) == 0:
        return media_types
    # Otherwise, enforce a media type like application/json to be able to parse nested array, but it won't be able to
    # support file upload...
    else:
        return non_form_media_types
Example #23
0
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, "serializer", None)
        if serializer and not getattr(serializer, "many", False):
            instance = getattr(serializer, "instance", None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        # If this is valid serializer data, and the form is for the same
        # HTTP method as was used in the request then use the existing
        # serializer instance, rather than dynamically creating a new one.
        if request.method == method and serializer is not None:
            try:
                kwargs = {"data": request.data}
            except ParseError:
                kwargs = {}
            existing_serializer = serializer
        else:
            kwargs = {}
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ("DELETE", "OPTIONS"):
                return True  # Don't actually need to return a form

            has_serializer = getattr(view, "get_serializer", None)
            has_serializer_class = getattr(view, "serializer_class", None)

            if (not has_serializer and not has_serializer_class) or not any(
                is_form_media_type(parser.media_type) for parser in view.parser_classes
            ):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if has_serializer:
                    if method in ("PUT", "PATCH"):
                        serializer = view.get_serializer(instance=instance, **kwargs)
                    else:
                        serializer = view.get_serializer(**kwargs)
                else:
                    # at this point we must have a serializer_class
                    if method in ("PUT", "PATCH"):
                        serializer = self._get_serializer(
                            view.serializer_class, view, request, instance=instance, **kwargs
                        )
                    else:
                        serializer = self._get_serializer(view.serializer_class, view, request, **kwargs)

            if hasattr(serializer, "initial_data"):
                serializer.is_valid()

            form_renderer = self.form_renderer_class()
            return form_renderer.render(
                serializer.data,
                self.accepted_media_type,
                dict(list(self.renderer_context.items()) + [("template", "rest_framework/api_form.html")]),
            )
Example #24
0
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, "serializer", None)
        if serializer and not getattr(serializer, "many", False):
            instance = getattr(serializer, "instance", None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        # If this is valid serializer data, and the form is for the same
        # HTTP method as was used in the request then use the existing
        # serializer instance, rather than dynamically creating a new one.
        if request.method == method and serializer is not None:
            try:
                kwargs = {"data": request.data}
            except ParseError:
                kwargs = {}
            existing_serializer = serializer
        else:
            kwargs = {}
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ("DELETE", "OPTIONS"):
                return True  # Don't actually need to return a form

            has_serializer = getattr(view, "get_serializer", None)
            has_serializer_class = getattr(view, "serializer_class", None)

            if (not has_serializer and not has_serializer_class) or not any(
                    is_form_media_type(parser.media_type)
                    for parser in view.parser_classes):
                return

            if existing_serializer is not None:
                try:
                    return self.render_form_for_serializer(existing_serializer)
                except TypeError:
                    pass

            if has_serializer:
                if method in ("PUT", "PATCH"):
                    serializer = view.get_serializer(instance=instance,
                                                     **kwargs)
                else:
                    serializer = view.get_serializer(**kwargs)
            else:
                # at this point we must have a serializer_class
                if method in ("PUT", "PATCH"):
                    serializer = self._get_serializer(view.serializer_class,
                                                      view,
                                                      request,
                                                      instance=instance,
                                                      **kwargs)
                else:
                    serializer = self._get_serializer(view.serializer_class,
                                                      view, request, **kwargs)

            return self.render_form_for_serializer(serializer)
    def get_rendered_html_form(self, data, view, method, request):
        """
        Return a string representing a rendered HTML form, possibly bound to
        either the input or output data.

        In the absence of the View having an associated form then return None.
        """
        # See issue #2089 for refactoring this.
        serializer = getattr(data, 'serializer', None)
        if serializer and not getattr(serializer, 'many', False):
            instance = getattr(serializer, 'instance', None)
            if isinstance(instance, Page):
                instance = None
        else:
            instance = None

        # If this is valid serializer data, and the form is for the same
        # HTTP method as was used in the request then use the existing
        # serializer instance, rather than dynamically creating a new one.
        if request.method == method and serializer is not None:
            try:
                kwargs = {'data': request.data}
            except ParseError:
                kwargs = {}
            existing_serializer = serializer
        else:
            kwargs = {}
            existing_serializer = None

        with override_method(view, request, method) as request:
            if not self.show_form_for_method(view, method, request, instance):
                return

            if method in ('DELETE', 'OPTIONS'):
                return True  # Don't actually need to return a form

            has_serializer = getattr(view, 'get_serializer', None)
            has_serializer_class = getattr(view, 'serializer_class', None)

            if (
                (not has_serializer and not has_serializer_class) or
                not any(is_form_media_type(parser.media_type) for parser in view.parser_classes)
            ):
                return

            if existing_serializer is not None:
                serializer = existing_serializer
            else:
                if has_serializer:
                    if method in ('PUT', 'PATCH'):
                        serializer = view.get_serializer(instance=instance, **kwargs)
                    else:
                        serializer = view.get_serializer(**kwargs)
                else:
                    # at this point we must have a serializer_class
                    if method in ('PUT', 'PATCH'):
                        serializer = self._get_serializer(view.serializer_class, view,
                                                          request, instance=instance, **kwargs)
                    else:
                        serializer = self._get_serializer(view.serializer_class, view,
                                                          request, **kwargs)

            if hasattr(serializer, 'initial_data'):
                serializer.is_valid()

            form_renderer = self.form_renderer_class()
            return form_renderer.render(
                serializer.data,
                self.accepted_media_type,
                {'style': {'template_pack': 'rest_framework/horizontal'}}
            )
Example #26
0
 def _is_csv_upload(self, request):
     if is_form_media_type(request.content_type):
         if ('file' in request.data
                 and request.data['file'].name.lower().endswith('.csv')):
             return True
     return False