在Django中获取请求正文作为字符串

时间:2015-04-08 12:02:54

标签: python django

我正在向一个Django服务器发送一个带有JSON主体的POST请求(相当标准)。在服务器上,我需要使用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'

如何在应用正确的编码的情况下以字符串形式检索请求正文?

3 个答案:

答案 0 :(得分:37)

请求正文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将接受unicode字符串或字节sting,因此不需要解码步骤。

解码字符串时,我认为您可以安全地假设'utf-8' - 我无法找到明确的来源,但请参阅jQuery docs下面的引文:

  

注意:W3C XMLHttpRequest规范规定charset始终为UTF-8;指定另一个字符集不会强制浏览器更改编码。

在Python 3.6中,json.loads() accepts bytes or bytearrays。因此,您不需要解码request.body(假设它以UTF-8编码)。

答案 1 :(得分:1)

我相信您收到此请求的另一端在发送请求之前不会将数据转换为JSON。您必须在发送之前将数据转换为JSON,或者只是尝试在您的视图中访问request.body。

答案 2 :(得分:0)

如果您的目标是获得使用JSON发送到服务器的数据的字典,请避免自己解码正文的麻烦,并使用django已经提供的request.POST类似于字典的对象开箱即用。

因此,假设您将此发布到服务器:

{ 'foo': 'bar' }

然后使用以下方法

def my_handler(request):
    foo = request.POST['foo']
    print(foo)

bar打印到控制台