PUT request for image upload not working in django

2019-04-19 23:58发布

问题:

I am trying to upload an image in django rest using multipart/form-data in a PUT request and Pillow:

class ABC(APIView):
    parser_classes = (MultiPartParser,)
    def put(self, request):
        a = Image()
        a.image_url = request.data["image"]
        a.save()

class Image(models.Model):
      image_url = models.ImageField(upload_to='static/bills', blank=True)

I make a request which is a PUT request and a multipart/form-data. I end up getting a response code of 400 with the message:

{
  "detail": "Multipart form parse error - Invalid boundary in multipart: None"
}

Somehow this has broken just now. It was working fine when I wrote it the first time. Since then I have added few settings configuration for CORS requests like:

CORS_ORIGIN_ALLOW_ALL = True

CORS_ALLOW_HEADERS = (
    'x-requested-with',
    'content-type',
    'accept',
    'origin',
    'authorization',
    'x-csrftoken',
    'token',
    'x-device-id',
    'x-device-type',
    'x-push-id',
    'dataserviceversion',
    'maxdataserviceversion'
)
CORS_ALLOW_METHODS = (
        'GET',
        'POST',
        'PUT',
        'PATCH',
        'DELETE',
        'OPTIONS'
    )

Any ideas?

OPTIONS Request response:

Access-Control-Allow-Headers → x-requested-with, content-type, accept, origin, authorization, x-csrftoken, token, x-device-id, x-device-type, x-push-id, dataserviceversion, maxdataserviceversion
    Access-Control-Allow-Methods → GET, POST, PUT, PATCH, DELETE, OPTIONS
    Access-Control-Allow-Origin → *
    Access-Control-Max-Age → 86400
    Allow → GET, POST, DELETE, HEAD, OPTIONS
    Content-Type → application/json
    Date → Fri, 21 Aug 2015 06:23:28 GMT
    Server → WSGIServer/0.1 Python/2.7.6
    Vary → Accept
    X-Frame-Options → SAMEORIGIN

回答1:

Removing the content-type from the headers resolves this.



回答2:

Your error is telling you that the boundary for your multipart/form-data content of your request is invalid - in particular that is is None. This, by design, returns a 400 ("Bad Request") response code. The Error is raised here in the django code.

To enter that code branch with boundary equal to None means that the boundary option is not specified in the content-type header of your request.

boundary must be specified when using multipart/form-data in content-type as specified in RFC2046 (referred to by RFC2388) - in particular section 5.1.1

The Content-Type field for multipart entities requires one parameter, "boundary".

You say it has worked before, so you should check the code that you are using to make the request - something must have changed to mean that the boundary is not specified in the content-type.

N.B. I presume the request is code-generated, as <form method="put"> is invalid HTML and so a request generated by a browser given that HTML would be a GET rather than a PUT.



回答3:

You will typically want to use both FormParser and MultiPartParser together in order to fully support HTML form data.