Подтвердить что ты не робот

Получить тело запроса как строку в 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'.

Как получить тело запроса в виде строки с применением правильной кодировки?

4b9b3361

Ответ 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 на консоли