¿Dónde están mis datos JSON en mi solicitud de Django entrante?

Estoy tratando de procesar solicitudes JSON / Ajax entrantes con Django / Python.

request.is_ajax() es True en la solicitud, pero no tengo idea de dónde está la carga útil con los datos JSON.

request.POST.dir contiene esto:

 ['__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'] 

Aparentemente no hay claves en las claves de post de solicitud.

Cuando miro el POST en Firebug , hay datos JSON que se envían en la solicitud.

    Si estás publicando JSON en Django, creo que quieres request.body ( request.raw_post_data en Django <1.4). Esto le dará los datos JSON en bruto enviados a través de la publicación. A partir de ahí podrás procesarlo más.

    Aquí hay un ejemplo usando JavaScript, jQuery , jquery-json y 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") 

    Yo tuve el mismo problema. Había estado publicando una compleja respuesta JSON, y no pude leer mis datos usando el diccionario request.POST.

    Mis datos JSON POST fueron:

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

    En este caso, debe utilizar el método proporcionado por aurealus. Lee el archivo request.body y deserialízalo con 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") 

    Método 1

    Cliente: Enviar como 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} 

    Servidor:

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

    Método 2

    Cliente: Enviar como x-www-form-urlencoded
    (Nota: contentType y processData han cambiado, JSON.stringify no es necesario)

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

    Servidor:

     data = request.POST # will be  

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

    Datos no formales en solicitudes HTTP :
    request.POST ya no incluirá los datos publicados a través de solicitudes HTTP con tipos de contenido no específicos del formulario en el encabezado. En versiones anteriores, los datos publicados con tipos de contenido distintos de multipart / form-data o application / x-www-form-urlencoded aún terminarán representados en el atributo request.POST. Los desarrolladores que deseen acceder a los datos POST sin procesar para estos casos, deben usar el atributo request.body en su lugar.

    Probablemente relacionado

    request.raw_response ahora está en desuso. Utilice request.body lugar para procesar datos de formularios no convencionales, como cargas útiles XML, imágenes binarias, etc.

    Django documentación sobre el tema .

    Es importante recordar que Python 3 tiene una forma diferente de representar cadenas: son matrices de bytes.

    Usando Django 1.9 y Python 2.7 y enviando los datos JSON en el cuerpo principal (no un encabezado), usarías algo como:

     mydata = json.loads(request.body) 

    Pero para Django 1.9 y Python 3.4 usarías:

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

    ¡Acabo de pasar por esta curva de aprendizaje haciendo mi primera aplicación Py3 Django!

    en django 1.6 python 3.3

    cliente

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

    servidor

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

    La carga útil HTTP POST es solo un montón de bytes. Django (como la mayoría de los marcos) lo decodifica en un diccionario a partir de parámetros codificados de URL, o encoding MIME multiparte. Si simplemente vuelcas los datos JSON en el contenido de la POST, Django no los descodificará. O bien decodifique JSON a partir del contenido completo de la POST (no del diccionario); o ponga los datos JSON en un envoltorio multiparte MIME.

    En definitiva, mostrar el código JavaScript. El problema parece estar ahí.

    request.raw_post_data ha quedado en desuso. Use request.body lugar

     html code file name : view.html        

    Select your favorite fruit:
    Django code: Inside views.py def view(request): if request.method == 'POST': print request.body data = request.body return HttpResponse(json.dumps(data))

    Algo como esto. Ha funcionado: solicitar datos al cliente.

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

    Procesar solicitud en el servidor.

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

    Usando Angular, debe agregar un encabezado para solicitarlo o agregarlo a los encabezados de configuración del módulo: {'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 es solo un objeto similar a un diccionario, así que solo indexe en él con la syntax dict.

    Suponiendo que tu campo de formulario sea fred, podrías hacer algo como esto:

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

    Alternativamente, use un objeto de formulario para tratar con los datos POST.