Allow body on HTTP DELETE view methods (#122)
* Allow body in delete requests * Do not add request body to DELETE by default * Check manual form parameters against body_methods * Add tests * Add changelog Closes #118openapi3 1.7.4
parent
3077195396
commit
aca0c4713e
|
|
@ -12,6 +12,7 @@ Changelog
|
|||
- **IMPROVED:** updated ``swagger-ui`` to version 3.14.2
|
||||
- **IMPROVED:** updated ``ReDoc`` to version 2.0.0-alpha.20
|
||||
- **FIXED:** ignore ``None`` return from ``get_operation`` to avoid empty ``Path`` objects in output
|
||||
- **FIXED:** request body is now allowed on ``DELETE`` endpoints (:issue:`118`)
|
||||
|
||||
*********
|
||||
**1.7.3**
|
||||
|
|
|
|||
|
|
@ -276,7 +276,10 @@ class SerializerInspector(FieldInspector):
|
|||
|
||||
|
||||
class ViewInspector(BaseInspector):
|
||||
body_methods = ('PUT', 'PATCH', 'POST') #: methods that are allowed to have a request body
|
||||
body_methods = ('PUT', 'PATCH', 'POST', 'DELETE') #: methods that are allowed to have a request body
|
||||
|
||||
#: methods that are assumed to require a request body determined by the view's ``serializer_class``
|
||||
implicit_body_methods = ('PUT', 'PATCH', 'POST')
|
||||
|
||||
# real values set in __init__ to prevent import errors
|
||||
field_inspectors = [] #:
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ class SwaggerAutoSchema(ViewInspector):
|
|||
if isinstance(body_override, openapi.Schema.OR_REF):
|
||||
return body_override
|
||||
return force_serializer_instance(body_override)
|
||||
elif self.method in self.body_methods:
|
||||
elif self.method in self.implicit_body_methods:
|
||||
return self.get_view_serializer()
|
||||
|
||||
return None
|
||||
|
|
@ -144,8 +144,11 @@ class SwaggerAutoSchema(ViewInspector):
|
|||
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
|
||||
if any(param.in_ == openapi.IN_BODY for param in parameters.values()):
|
||||
raise SwaggerGenerationError("cannot add form parameters when the request has a request schema; "
|
||||
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")
|
||||
|
||||
parameters.update(param_list_to_odict(manual_parameters))
|
||||
return list(parameters.values())
|
||||
|
|
|
|||
|
|
@ -33,6 +33,21 @@ class SnippetList(generics.ListCreateAPIView):
|
|||
"""post method docstring"""
|
||||
return super(SnippetList, self).post(request, *args, **kwargs)
|
||||
|
||||
@swagger_auto_schema(
|
||||
operation_id='snippets_delete_bulk',
|
||||
request_body=openapi.Schema(
|
||||
type=openapi.TYPE_OBJECT,
|
||||
properties={
|
||||
'body': openapi.Schema(
|
||||
type=openapi.TYPE_STRING,
|
||||
description='this should not crash (request body on DELETE method)'
|
||||
)
|
||||
}
|
||||
),
|
||||
)
|
||||
def delete(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
|
||||
class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
|
||||
"""
|
||||
|
|
@ -56,18 +71,26 @@ class SnippetDetail(generics.RetrieveUpdateDestroyAPIView):
|
|||
"""patch method docstring"""
|
||||
return super(SnippetDetail, self).patch(request, *args, **kwargs)
|
||||
|
||||
@swagger_auto_schema(manual_parameters=[
|
||||
openapi.Parameter(
|
||||
name='id', in_=openapi.IN_PATH,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
description="path parameter override",
|
||||
required=True
|
||||
),
|
||||
], responses={
|
||||
status.HTTP_204_NO_CONTENT: openapi.Response(
|
||||
description="This should not crash"
|
||||
)
|
||||
})
|
||||
@swagger_auto_schema(
|
||||
manual_parameters=[
|
||||
openapi.Parameter(
|
||||
name='id', in_=openapi.IN_PATH,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
description="path parameter override",
|
||||
required=True
|
||||
),
|
||||
openapi.Parameter(
|
||||
name='delete_form_param', in_=openapi.IN_FORM,
|
||||
type=openapi.TYPE_INTEGER,
|
||||
description="this should not crash (form parameter on DELETE method)"
|
||||
),
|
||||
],
|
||||
responses={
|
||||
status.HTTP_204_NO_CONTENT: openapi.Response(
|
||||
description="this should not crash (response object with no schema)"
|
||||
)
|
||||
}
|
||||
)
|
||||
def delete(self, request, *args, **kwargs):
|
||||
"""delete method docstring"""
|
||||
return super(SnippetDetail, self).patch(request, *args, **kwargs)
|
||||
|
|
|
|||
|
|
@ -388,6 +388,24 @@ paths:
|
|||
$ref: '#/definitions/Snippet'
|
||||
tags:
|
||||
- snippets
|
||||
delete:
|
||||
operationId: snippetsDeleteBulk
|
||||
description: SnippetList classdoc
|
||||
parameters:
|
||||
- name: data
|
||||
in: body
|
||||
required: true
|
||||
schema:
|
||||
type: object
|
||||
properties:
|
||||
body:
|
||||
description: this should not crash (request body on DELETE method)
|
||||
type: string
|
||||
responses:
|
||||
'204':
|
||||
description: ''
|
||||
tags:
|
||||
- snippets
|
||||
parameters: []
|
||||
/snippets/{id}/:
|
||||
get:
|
||||
|
|
@ -442,9 +460,13 @@ paths:
|
|||
description: path parameter override
|
||||
required: true
|
||||
type: integer
|
||||
- name: delete_form_param
|
||||
in: formData
|
||||
description: this should not crash (form parameter on DELETE method)
|
||||
type: integer
|
||||
responses:
|
||||
'204':
|
||||
description: This should not crash
|
||||
description: this should not crash (response object with no schema)
|
||||
tags:
|
||||
- snippets
|
||||
parameters:
|
||||
|
|
|
|||
Loading…
Reference in New Issue