I'm using drf-spectacular to generate swagger/redoc API documentation.
One of the most useful features is the ability to test requests via the generated swagger html page, but I'd like to enforce the application/x-www-form-urlencoded content-type so that when the request is received by my Django endpoints, the request.data has the encoded data instead of it ending up as part of a query string. drf-spectacular always seems to default to query strings e.g. /objects/action/?key=value
The only way I've figured out how to do this is to use a serializer in conjunction with the request content-type e.g.
@extend_schema(
request={'application/x-www-form-urlencoded': DoTheActionInputsSerializer},
responses={200: DoTheActionOutputsSerializer},
methods=["POST"]
)
@action(methods=['post'], detail=False)
def do_the_action(self, request, *args, **kwargs):
...
This works great, but it does require a lot of small serializers that may only have one or two attributes. Is there an alternative way of achieving this inside the extend_schema decorator?
I was hoping something like the following would work, but doesn't
request={'application/x-www-form-urlencoded': {'schema': {'foo_id': OpenApiTypes.INT}}},
I think the documentation answers that question. You can use inline_serializer
for those small one-off cases. It allows you to do this:
@extend_schema(responses={
'2XX': SimpleSerializer,
'401': inline_serializer('Error1', fields={'detail': serializers.CharField()}),
})
This works the same for @extend_schema(request=inline_serializer(...))
As a matter of last resort, you can also put a raw schema dict into request
or response
.
Note: If you want application/x-www-form-urlencoded
to be detected automatically, just do
@action(methods=['post'], detail=False, parser_classes=[parsers.FormParser])