Get request body as string in Django
django, python
Solution
The request body, `request.body`, is a byte string. In Python 3.0 to 3.5.x, `json.loads()` will only accept a unicode string, so you must decode `request.body` before passing it to `json.loads()`.
body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
In Python 2, `json.loads` will accept a unicode string or a byte sting, so the decode step is not necessary.
When decoding the string, I think you're safe to assume 'utf-8' - I can't find a definitive source for this, but see the quote below from the jQuery docs:
Note: The W3C XMLHttpRequest specification dictates that the charset is always UTF-8; specifying another charset will not force the browser to change the encoding.
In Python 3.6, `json.loads()` accepts bytes or bytearrays. Therefore you shouldn't need to decode `request.body` (assuming it's encoded in UTF-8).
Problem
I'm sending a POST request with JSON body to a Django server (fairly standard). On the server I need to decode this using `json.loads()`. The problem is how do I get the body of the request in a string format? I have the following code currently: ``` body_data = {} if request.META.get('CONTENT_TYPE', '').lower() == 'application/json' and len(request.body) > 0: try: body_data = json.loads(request.body) except Exception as e: return HttpResponseBadRequest(json.dumps({'error': 'Invalid request: {0}'.format(str(e))}), content_type="application/json") ``` However, this gives an error `the JSON object must be str, not 'bytes'`. How do I retrieve the body of the request as a string, with the correct encoding applied?