web-dev-qa-db-fra.com

Où sont mes données JSON dans ma demande entrante Django?

J'essaie de traiter les demandes JSON/Ajax entrantes avec Django/Python.

request.is_ajax() est True sur la demande, mais je ne sais pas du tout où se trouve la charge utile avec les données JSON.

request.POST.dir contient ceci:

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

Il n'y a apparemment pas de clés dans les clés de poste de demande.

Lorsque je regarde le POST dans Firebug , il y a des données JSON envoyées dans la demande.

144
user122299

Si vous publiez du JSON sur Django, je pense que vous voulez request.body (request.raw_post_data on Django <1.4). Cela vous donnera les données JSON brutes envoyées par la poste. De là, vous pouvez le traiter plus loin.

Voici un exemple utilisant JavaScript, jQuery , jquery-json et 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")
215
Jared Knipp

J'ai eu le même problème. J'avais posté une réponse JSON complexe et je ne pouvais pas lire mes données à l'aide du dictionnaire request.POST.

Mes données JSON POST étaient:

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

Dans ce cas, vous devez utiliser la méthode fournie par aurealus. Lisez le request.body et désérialisez-le avec 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")
61
stricjux

Méthode 1

Client: Envoyer en tant que 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}

Serveur:

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

Méthode 2

Client: Envoyer en tant que x-www-form-urlencoded
(Remarque: contentType & processData ont changé, JSON.stringify n'est pas nécessaire)

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

Serveur:

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

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

Données non-formulaire dans les requêtes HTTP :
request.POST n'inclura plus les données publiées via des requêtes HTTP avec des types de contenu non spécifiques à un formulaire dans l'en-tête. Dans les versions précédentes, les données publiées avec des types de contenu autres que multipart/form-data ou application/x-www-form-urlencoded étaient toujours représentées dans l'attribut request.POST. Les développeurs souhaitant accéder aux données brutes POST pour ces cas) doivent utiliser l'attribut request.body à la place.

Probablement lié

33
user

request.raw_response est maintenant obsolète. Utilisation request.body au lieu de traiter des données de formulaire non conventionnelles telles que des charges utiles XML, des images binaires, etc.

documentation Django sur le problème .

23
Kevin S Lin

Il est important de se rappeler Python 3 a une manière différente de représenter des chaînes - ce sont des tableaux d'octets.

En utilisant Django 1.9 et Python 2.7) et en envoyant les données JSON dans le corps principal (pas un en-tête), vous utiliseriez quelque chose comme:

mydata = json.loads(request.body)

Mais pour Django 1.9 et Python 3.4, vous utiliseriez:

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

Je viens de passer par cette courbe d’apprentissage en créant mon premier Py3 Django app!

16
Richard Cooke

sur Django 1.6 python 3.3

client

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

serveur

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")))
9
Rubber Duck

request.raw_post_data est obsolète. Utilisation request.body au lieu

5
Andres

La charge HTTP POST est juste un tas d'octets. Django (comme la plupart des frameworks) le décode dans un dictionnaire à partir de paramètres encodés en URL, ou d'encodage MIME en plusieurs parties. Si vous ne faites que vider les données JSON dans le contenu POST, Django ne les décodera pas. Soit le JSON décodant à partir du contenu complet POST (pas du dictionnaire); ou placez les données JSON dans un wrapper MIME multipart.

En bref, affichez le code JavaScript. Le problème semble être là.

5
Javier

Quelque chose comme ça. C'est travaillé: Demander des données au client

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

Demande de processus sur le serveur

@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")
3
Nghia Tu
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))
2
Rajan Mandanka