Skip to content

Commit

Permalink
improve parameter many handling and warnings #703
Browse files Browse the repository at this point in the history
  • Loading branch information
tfranzel committed Apr 21, 2022
1 parent ef0d828 commit 4b7eee7
Show file tree
Hide file tree
Showing 4 changed files with 53 additions and 2 deletions.
16 changes: 14 additions & 2 deletions drf_spectacular/openapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -157,10 +157,22 @@ def _process_override_parameters(self):

if is_basic_type(parameter.type):
schema = build_basic_type(parameter.type)
elif is_serializer(parameter.type):
elif is_basic_serializer(parameter.type):
schema = self.resolve_serializer(parameter.type, 'request').ref
else:
elif isinstance(parameter.type, dict):
schema = parameter.type
else:
warn(f'unsupported type for parameter "{parameter.name}". Skipping.')
continue

if parameter.many:
if is_basic_type(parameter.type):
schema = build_array_type(schema)
else:
warn(
f'parameter "{parameter.name}" has many=True and is not a basic type. '
f'many=True only makes sense for basic types. Ignoring.'
)

if parameter.exclude:
result[parameter.name, parameter.location] = None
Expand Down
2 changes: 2 additions & 0 deletions drf_spectacular/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,7 @@ def __init__(
explode: Optional[bool] = None,
default: Any = None,
allow_blank: bool = True,
many: Optional[bool] = None,
examples: Optional[List[OpenApiExample]] = None,
extensions: Optional[Dict[str, Any]] = None,
exclude: bool = False,
Expand All @@ -188,6 +189,7 @@ def __init__(
self.explode = explode
self.default = default
self.allow_blank = allow_blank
self.many = many
self.examples = examples or []
self.extensions = extensions
self.exclude = exclude
Expand Down
16 changes: 16 additions & 0 deletions tests/test_regressions.py
Original file line number Diff line number Diff line change
Expand Up @@ -2852,3 +2852,19 @@ def view_func(request, format=None):

schema = generate_schema('/x/', view_function=view_func)
assert schema['paths']['/x/']['get']['externalDocs'] == {'url': 'https://example.com'}


def test_basic_parameters_with_many(no_warnings):
@extend_schema(
request=OpenApiTypes.ANY,
responses=OpenApiTypes.ANY,
parameters=[OpenApiParameter(name='test', type=int, many=True)]
)
@api_view(['POST'])
def view_func(request, format=None):
pass # pragma: no cover

schema = generate_schema('/x/', view_function=view_func)
assert schema['paths']['/x/']['post']['parameters'][0]['schema'] == {
'type': 'array', 'items': {'type': 'integer'}
}
21 changes: 21 additions & 0 deletions tests/test_warnings.py
Original file line number Diff line number Diff line change
Expand Up @@ -479,3 +479,24 @@ def view_func(request, format=None):

stderr = capsys.readouterr().err
assert 'illegal characters' in stderr


@pytest.mark.parametrize('type_arg,many', [
(SimpleSerializer, True),
(SimpleSerializer(many=True), None),
(serializers.ListSerializer(child=serializers.CharField()), None),
(serializers.ListField(child=serializers.CharField()), None),
])
def test_invalid_parameter_types(capsys, type_arg, many):
@extend_schema(
request=OpenApiTypes.ANY,
responses=OpenApiTypes.ANY,
parameters=[OpenApiParameter(name='test', type=type_arg, many=many)]
)
@api_view(['POST'])
def view_func(request, format=None):
pass # pragma: no cover

generate_schema('/x/', view_function=view_func)
stderr = capsys.readouterr().err
assert 'parameter "test"' in stderr

0 comments on commit 4b7eee7

Please sign in to comment.