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

时间:2009-07-30 17:22:54

标签: python ajax json django content-type

我正在尝试使用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数据。

12 个答案:

答案 0 :(得分:203)

如果您要将JSON发布到Django,我认为您需要request.body(Django上的request.raw_post_data< 1.4)。这将为您提供通过帖子发送的原始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")

答案 1 :(得分:57)

我遇到了同样的问题。我一直在发布一个复杂的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);

在这种情况下,您需要使用aurealus提供的方法。读取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")

答案 2 :(得分:32)

方法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
(注意:contentType&amp; processData已更改,不需要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请求发布的数据   标头中非特定于表单的内容类型。在以前的版本中,数据   发布的内容类型不是multipart / form-data或   application / x-www-form-urlencoded仍将最终代表   request.POST属性。希望访问原始POST的开发人员   这些情况的数据应该使用request.body属性。

可能相关

答案 3 :(得分:23)

request.raw_response现已弃用。使用request.body代替处理非常规表单数据,例如XML有效负载,二进制映像等。

Django documentation on the issue

答案 4 :(得分:16)

重要的是要记住Python 3有一种不同的表示字符串的方式 - 它们是字节数组。

使用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应用程序!

答案 5 :(得分:8)

on django 1.6 python 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")))

答案 6 :(得分:5)

HTTP POST有效负载只是一堆字节。 Django(与大多数框架一样)根据URL编码参数或MIME多部分编码将其解码为字典。如果您只是将JSON数据转储到POST内容中,Django将不会解码它。从完整的POST内容(不是字典)中进行JSON解码;或者将JSON数据放入MIME多部分包装器中。

简而言之,请显示JavaScript代码。问题似乎就在那里。

答案 7 :(得分:5)

request.raw_post_data已被弃用。请改用request.body

答案 8 :(得分:3)

像这样的东西。它的工作原理是: 从客户

请求数据
<div style="text-align: center;font-size: 56px; font-weight: 200; margin: 140px 0;">

    <div style="margin-top: 50px;">
        <a href="<?php echo GOOGLE_PLAY_LINK; ?>" rel="nofollow">
            <img src="/img/googleplay.png">
        </a>
    </div>
    <div style="margin-top: 40px; font-size: 22px;">
        <a style="color: #3A6DA5" href="/admin/login.php">Go to admin panel -></a>
    </div>
</div>

服务器上的处理请求

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);
});

答案 9 :(得分:2)

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))

答案 10 :(得分:-2)

使用Angular,您应该添加标头以请求或将其添加到模块配置 标题:{'Content-Type': 'application/x-www-form-urlencoded'}

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

答案 11 :(得分:-4)

request.POST只是一个类字典对象,所以只需用dict语法索引它。

假设您的表单字段是fred,您可以执行以下操作:

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

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