Получить тело запроса как строку в Django
Я отправляю запрос POST с телом JSON на сервер Django (довольно стандартный). На сервере мне нужно декодировать это с помощью json.loads()
.
Проблема в том, как получить тело запроса в строковом формате?
В настоящее время у меня есть следующий код:
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")
Однако это дает ошибку the JSON object must be str, not 'bytes'
.
Как получить тело запроса в виде строки с применением правильной кодировки?
Ответы
Ответ 1
Тело запроса request.body
является байтовой строкой. В Python 3 json.loads()
будет принимать только строку unicode, поэтому вы должны декодировать request.body
, прежде чем передать ее в json.loads()
.
body_unicode = request.body.decode('utf-8')
body_data = json.loads(body_unicode)
В Python 2 json.loads
будет принимать строку юникода или байтов, поэтому шаг декодирования не требуется.
При декодировании строки я думаю, что вы можете предположить "utf-8" - я не могу найти для этого окончательный источник, но см. приведенную ниже цитату из jQuery docs:
Примечание. Спецификация W3C XMLHttpRequest требует, чтобы кодировка всегда была UTF-8; указание другой кодировки не заставит браузер изменить кодировку.
В Python 3.6, json.loads()
принимает байты или bytearrays. Поэтому вам не нужно декодировать request.body
(предполагая, что он закодирован в UTF-8).
Ответ 2
Я считаю, что другой конец, откуда вы получаете этот запрос, не передает данные в JSON перед отправкой запроса. Либо вы должны преобразовать данные в JSON перед отправкой, либо просто попробовать получить доступ к request.body в вашем представлении.
Ответ 3
Если ваша цель состоит в том, чтобы получить словарь данных, которые вы только что отправили на сервер с помощью JSON, избавьте себя от необходимости самостоятельно декодировать тело и использовать объект request.POST
словарь, который django уже предоставляет вне -Box.
Итак, предположим, что вы размещаете это на сервере:
{ 'foo': 'bar' }
Тогда следующий метод
def my_handler(request):
foo = request.POST['foo']
print(foo)
Будет ли печатать bar
на консоли