2015-04-08 8 views
13

Я отправляю запрос POST с телом JSON на сервер Django (довольно стандартный). На сервере мне нужно декодировать это, используя json.loads().Получить тело запроса как строку в Django

Проблема в том, как получить тело запроса в строковом формате?

У меня есть следующий код в настоящее время:

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'.

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

+0

Выполняет ли 'request.read()' работу? – dhke

+0

@dhke, нет, это дает то же самое, что меня действительно удивило. 'request.body.decode ('utf-8')', похоже, работает, но я не уверен, что это лучший способ сделать это? – zelanix

ответ

26

Тело запроса, request.body, является байтовой строкой. В Python 3, json.loads() будет принимать только строку юникода, поэтому вы должны декодировать 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() accepts bytes or bytearrays. Поэтому вам не нужно декодировать request.body (при условии, что он закодирован в UTF-8).

+0

Отлично, спасибо за разъяснение этого :) – zelanix

+2

'utf-8' также является значением по умолчанию для первого аргумента метода' decode() '(check' help (bytes.decode) ') – rednaw

+2

В Python> = 3.6, 'json.loads' может также принимать аргумент' bytes', и предполагается, что он закодирован в UTF-8, UTF-16 или UTF-32. https://docs.python.org/3/library/json.html#json.loads – Flimm

0

Я считаю, что на другом конце, откуда вы получаете этот запрос, не пересылаются данные в JSON перед отправкой запроса. Либо вы должны преобразовать данные в JSON перед отправкой, либо просто попытаться получить доступ к request.body в своем представлении.

+1

Спасибо за ответ. Я думаю, что это действительно json, хотя - если я использую 'request.body.decode ('utf-8')', то он работает. Есть ли причина не делать этого, скажете вы? – zelanix

Смежные вопросы