我的传入Django请求中的JSON数据在哪里?

我试图用Django / Python来处理传入的JSON / Ajax请求。

request.is_ajax()True ,但我不知道JSON数据的有效载荷在哪里。

request.POST.dir包含这个:

 ['__class__', '__cmp__', '__contains__', '__copy__', '__deepcopy__', '__delattr__', '__delitem__', '__dict__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setitem__', '__str__', '__weakref__', '_assert_mutable', '_encoding', '_get_encoding', '_mutable', '_set_encoding', 'appendlist', 'clear', 'copy', 'encoding', 'fromkeys', 'get', 'getlist', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'lists', 'pop', 'popitem', 'setdefault', 'setlist', 'setlistdefault', 'update', 'urlencode', 'values'] 

请求发布键中显然没有键。

当我在Firebug中查看POST时,在请求中发送了JSON数据。

如果您将JSON发布到Django,我想您需要request.body (Django <1.4上的request.raw_post_data )。 这会给你通过post发送的原始JSON数据。 从那里你可以进一步处理。

这里是一个使用JavaScript, jQuery ,jQuery-json和Django的例子。

JavaScript的:

 var myEvent = {id: calEvent.id, start: calEvent.start, end: calEvent.end, allDay: calEvent.allDay }; $.ajax({ url: '/event/save-json/', type: 'POST', contentType: 'application/json; charset=utf-8', data: $.toJSON(myEvent), dataType: 'text', success: function(result) { alert(result.Result); } }); 

Django的:

 def save_events_json(request): if request.is_ajax(): if request.method == 'POST': print 'Raw Data: "%s"' % request.body return HttpResponse("OK") 

Django <1.4:

  def save_events_json(request): if request.is_ajax(): if request.method == 'POST': print 'Raw Data: "%s"' % request.raw_post_data return HttpResponse("OK") 

我有同样的问题。 我一直在发布一个复杂的JSON响应,我无法使用request.POST字典读取我的数据。

我的JSON POST数据是:

 //JavaScript code: //Requires json2.js and jQuery. var response = {data:[{"a":1, "b":2},{"a":2, "b":2}]} json_response = JSON.stringify(response); // proper serialization method, read // http://ejohn.org/blog/ecmascript-5-strict-mode-json-and-more/ $.post('url',json_response); 

在这种情况下,您需要使用金黄色葡萄球菌提供的方法。 阅读request.body并用json stdlib反序列化它。

 #Django code: import json def save_data(request): if request.method == 'POST': json_data = json.loads(request.body) # request.raw_post_data w/ Django < 1.4 try: data = json_data['data'] except KeyError: HttpResponseServerError("Malformed data!") HttpResponse("Got json data") 

方法1

客户端:以JSON发送

 $.ajax({ url: 'example.com/ajax/', type: 'POST', contentType: 'application/json; charset=utf-8', processData: false, data: JSON.stringify({'name':'John', 'age': 42}), ... }); //Sent as a JSON object {'name':'John', 'age': 42} 

服务器:

 data = json.loads(request.body) # {'name':'John', 'age': 42} 

方法2

客户:以x-www-form-urlencoded
(注意: contentTypeprocessData已经改变, JSON.stringify

 $.ajax({ url: 'example.com/ajax/', type: 'POST', data: {'name':'John', 'age': 42}, contentType: 'application/x-www-form-urlencoded; charset=utf-8', //Default processData: true, }); //Sent as a query string name=John&age=42 

服务器:

 data = request.POST # will be <QueryDict: {u'name':u'John', u'age': 42}> 

改为1.5+: https : //docs.djangoproject.com/en/dev/releases/1.5/#non-form-data-in-http-requests

HTTP请求中的非表单数据
request.POST将不再包含通过HTTP请求发布的数据,并且头中没有特定于表单的内容types。 在之前的版本中,使用除multipart / form-data或application / x-www-form-urlencoded以外的其他内容types发布的数据仍然会以request.POST属性表示。 希望访问这些情况下的原始POST数据的开发人员应该使用request.body属性。

可能相关

request.raw_response现已被弃用。 使用request.body来处理非常规的表单数据,如XML有效载荷,二进制图像等

关于这个问题的Django文档 。

重要的是要记住Python 3有不同的方式来表示string – 它们是字节数组。

使用Django 1.9和Python 2.7并在主体(而不是头)中发送JSON数据,你会使用类似于:

 mydata = json.loads(request.body) 

但是对于Django 1.9和Python 3.4,你可以使用:

 mydata = json.loads(request.body.decode("utf-8")) 

我刚刚通过这个学习曲线,使我的第一个Py3的Django应用程序!

在Django的1.6蟒3.3

客户

 $.ajax({ url: '/urll/', type: 'POST', contentType: 'application/json; charset=utf-8', data: JSON.stringify(json_object), dataType: 'json', success: function(result) { alert(result.Result); } }); 

服务器

 def urll(request): if request.is_ajax(): if request.method == 'POST': print ('Raw Data:', request.body) print ('type(request.body):', type(request.body)) # this type is bytes print(json.loads(request.body.decode("utf-8"))) 

HTTP POST有效载荷只是一堆扁平的字节。 Django(像大多数框架一样)将其解码为来自URL编码参数或MIME多部分编码的字典。 如果您只是在POST内容中转储JSON数据,Django将不会对其进行解码。 要么从完整的POST内容(而不是字典)进行JSON解码; 或将JSON数据放入MIME多部分封装器中。

总之,显示JavaScript代码。 问题似乎在那里。

request.raw_post_data已被弃用。 使用request.body代替

 html code file name : view.html <!DOCTYPE html> <html> <head> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <script> $(document).ready(function(){ $("#mySelect").change(function(){ selected = $("#mySelect option:selected").text() $.ajax({ type: 'POST', dataType: 'json', contentType: 'application/json; charset=utf-8', url: '/view/', data: { 'fruit': selected }, success: function(result) { document.write(result) } }); }); }); </script> </head> <body> <form> <br> Select your favorite fruit: <select id="mySelect"> <option value="apple" selected >Select fruit</option> <option value="apple">Apple</option> <option value="orange">Orange</option> <option value="pineapple">Pineapple</option> <option value="banana">Banana</option> </select> </form> </body> </html> Django code: Inside views.py def view(request): if request.method == 'POST': print request.body data = request.body return HttpResponse(json.dumps(data)) 

像这样的东西。 它的工作:从客户端请求数据

 registerData = { {% for field in userFields%} {{ field.name }}: {{ field.name }}, {% endfor %} } var request = $.ajax({ url: "{% url 'MainApp:rq-create-account-json' %}", method: "POST", async: false, contentType: "application/json; charset=utf-8", data: JSON.stringify(registerData), dataType: "json" }); request.done(function (msg) { [alert(msg);] alert(msg.name); }); request.fail(function (jqXHR, status) { alert(status); }); 

在服务器上处理请求

 @csrf_exempt def rq_create_account_json(request): if request.is_ajax(): if request.method == 'POST': json_data = json.loads(request.body) print(json_data) return JsonResponse(json_data) return HttpResponse("Error") 

使用Angular你应该添加头文件到请求或添加到模块configuration头文件: {'Content-Type': 'application/x-www-form-urlencoded'}

 $http({ url: url, method: method, timeout: timeout, data: data, headers: {'Content-Type': 'application/x-www-form-urlencoded'} }) 

request.POST只是一个类似字典的对象,所以只需要用dict语法进行索引即可。

假设你的表单域是fred,你可以这样做:

 if 'fred' in request.POST: mydata = request.POST['fred'] 

或者,使用表单对象来处理POST数据。