DRF doesn't change the media type of request body to multipart/form-data automatically · Issue #6863 · encode/django-rest-framework (original) (raw)

Checklist

Steps to reproduce

# view.py
from rest_framework import generics
from rest_framework import serializers
from django.db import models

class Book(models.Model):
  title = models.CharField(max_length=200)

class BookSerializer(serializers.ModelSerializer):
  cover = serializers.FileField()
  class Meta:
    model = Book
    fields = ('cover',)

class BooksView(generics.CreateAPIView):
  queryset = Book.objects.all()   
  serializer_class = BookSerializer

# urls.py
urlpatterns = [
...
path('api/books/', views.BooksView.as_view()),
...
]

Expected behavior

./manage.py generateschema 
openapi: 3.0.2
info:
  title: ''
  version: TODO
paths:
  /api/books/:
    post:
      operationId: CreateBook
      parameters: []
      requestBody:
        content:
          multipart/form-data:
            schema:
              required:
              - cover
              properties:
                cover:
                  type: string
                  format: binary
      responses:
        '200':
          content:
            application/json:
              schema:
                required:
                - cover
                properties:
                  cover:
                    type: string

Actual behavior

./manage.py generateschema 
openapi: 3.0.2
info:
  title: ''
  version: TODO
paths:
  /api/books/:
    post:
      operationId: CreateBook
      parameters: []
      requestBody:
        content:
          application/json:
            schema:
              required:
              - cover
              properties:
                cover:
                  type: string
      responses:
        '200':
          content:
            application/json:
              schema:
                required:
                - cover
                properties:
                  cover:
                    type: string

There are two things going on here:

  1. There is no support for automatic multipart/form-data media type generation
  2. The FileField generates incomplete OpenAPI schema: it doesn't include format: binary. Finally, it should only generate format: binary for requests, since you can't have a binary string field within application/json media type. We could probably add a format: uri in case use_url=True.

https://swagger.io/docs/specification/describing-request-body/multipart-requests/

On unrelated note I noticed that DRF doesn't put type: object under schema even though this spec passes validation here