request.data in DRF vs request.body in Django
You should use request.data
. It's more flexible, covers more use cases and it can be accessed as many times as needed. Quoting the docs:
Aboout request.data
REST framework introduces a Request object that extends the regular HttpRequest, and provides more flexible request parsing. The core functionality of the Request object is the request.data attribute, which is similar to request.POST, but more useful for working with Web APIs.
request.POST # Only handles form data. Only works for 'POST' method.
request.data # Handles arbitrary data. Works for 'POST', 'PUT' and 'PATCH' methods.
About request.body
The raw HTTP request body as a byte string. This is useful for processing data in different ways than conventional HTML forms: binary images, XML payload etc. For processing conventional form data, use HttpRequest.POST.
So unless you want to handle binary images or XML payload, never use request.body
, it'll only be a simple string containing, well, the body of the request. Always use request.data
which'll be the fully parsed body (i.e. a Python dict
) which is much more convenient to handle.
In rest_framework.request.Request
request.body
is bytes, which is always available, thus there is no limit in usagerequest.data
is a "property" method and can raise an exception, but it gives you parsed data, which are more convenient
However, the world is not perfect and here is a case when request.body
win
Consider this example:
If client send:
content-type: text/plain
and your REST's endpoint doesn't accept text/plain
your server will return 415 Unsupported Media Type
if you access request.data
But what if you know that json.loads(request.body)
is correct json.
So you want to use that and only request.body
allow that.
FYI: A described example is a message of AWS SNS notification sent by AWS to HTTP endpoint. AWS SNS works as a client here and of course, this case is a bug in their SNS.
Another example of benefits from request.body
is a case when you have own custom parsing and you use own MIME format.