Création d'une réponse JSON à l'aide de Django et Python


452

J'essaie de convertir un script de réponse Ajax côté serveur en Django HttpResponse, mais apparemment, cela ne fonctionne pas.

Voici le script côté serveur:

/* RECEIVE VALUE */
$validateValue=$_POST['validateValue'];
$validateId=$_POST['validateId'];
$validateError=$_POST['validateError'];

/* RETURN VALUE */
$arrayToJs = array();
$arrayToJs[0] = $validateId;
$arrayToJs[1] = $validateError;

if($validateValue =="Testuser"){  // Validate??
    $arrayToJs[2] = "true";       // RETURN TRUE
    echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';  // RETURN ARRAY WITH success
}
else{
    for($x=0;$x<1000000;$x++){
        if($x == 990000){
            $arrayToJs[2] = "false";
            echo '{"jsonValidateReturn":'.json_encode($arrayToJs).'}';   // RETURNS ARRAY WITH ERROR.
        }
    }
}

Et voici le code converti

def validate_user(request):
    if request.method == 'POST':
        vld_value = request.POST.get('validateValue')
        vld_id = request.POST.get('validateId')
        vld_error = request.POST.get('validateError')

        array_to_js = [vld_id, vld_error, False]

        if vld_value == "TestUser":
            array_to_js[2] = True
            x = simplejson.dumps(array_to_js)
            return HttpResponse(x)
        else:
            array_to_js[2] = False
            x = simplejson.dumps(array_to_js)
            error = 'Error'
            return render_to_response('index.html',{'error':error},context_instance=RequestContext(request))
    return render_to_response('index.html',context_instance=RequestContext(request))

J'utilise simplejson pour encoder la liste Python (il retournera donc un tableau JSON). Je ne pouvais pas encore comprendre le problème. Mais je pense que j'ai fait quelque chose de mal à propos de «l'écho».


Vous pouvez également utiliser le décorateur de vue ennuyeux pour Django @ajax_request.
zopieux

Réponses:


917

J'utilise généralement un dictionnaire, pas une liste pour renvoyer du contenu JSON.

import json

from django.http import HttpResponse

response_data = {}
response_data['result'] = 'error'
response_data['message'] = 'Some error message'

Avant Django 1.7, vous le renverriez comme ceci:

return HttpResponse(json.dumps(response_data), content_type="application/json")

Pour Django 1.7+, utilisez JsonResponsecomme indiqué dans cette réponse SO comme ceci:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

4
Il est le type MIME, pas la liste qui devrait être lui attirer des ennuis. Alors que la plupart des JSON sont généralement un objet ("dictionnaire") au niveau supérieur, JSON est parfaitement satisfait d'un tableau au niveau supérieur.
Thanatos

6
Désolé, ce n'est pas clair d'après ce que j'ai écrit, mais je voulais seulement dire que j'utilise un dictionnaire parce qu'il est plus propre / plus facile lors de sa sérialisation en JSON.
Tom

'application / json' n'est pas correctement pris en charge dans les anciennes versions d'IE. Voici une discussion du problème github.com/blueimp/jQuery-File-Upload/issues/123
Victory

161

Nouveau dans Django 1.7

vous pouvez utiliser des objets JsonResponse .

à partir des documents:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})

2
Un inconvénient: il est par défaut ensure_asciiet je n'ai pas encore trouvé de moyen de le contourner. Créé une nouvelle question pour ceci: stackoverflow.com/q/34798703/854477
int_ua

@int_ua: il suffit d'ajouter json_dumps_params={"ensure_ascii": False}(nécessite Django 1.9 ou plus récent)
Martijn Pieters

139

J'utilise ça, ça marche bien.

from django.utils import simplejson
from django.http import HttpResponse

def some_view(request):
    to_json = {
        "key1": "value1",
        "key2": "value2"
    }
    return HttpResponse(simplejson.dumps(to_json), mimetype='application/json')

Alternative:

from django.utils import simplejson

class JsonResponse(HttpResponse):
    """
        JSON response
    """
    def __init__(self, content, mimetype='application/json', status=None, content_type=None):
        super(JsonResponse, self).__init__(
            content=simplejson.dumps(content),
            mimetype=mimetype,
            status=status,
            content_type=content_type,
        )

Dans Django 1.7, des objets JsonResponse ont été ajoutés au framework Django lui-même, ce qui rend cette tâche encore plus facile:

from django.http import JsonResponse
def some_view(request):
    return JsonResponse({"key": "value"})

1
Le problème est ici qu'il n'obtient pas la valeur du champ d'entrée vld_value = request.POST.get ('validateValue')
Switch

2
Avec python 2.7, il devrait juste être "import json"
Cullen Fluffy Jennings

1
Je pense que from django.utils import simplejsonc'est pour une compatibilité descendante.
Skylar Saveland

JsonResponse(status=404, data={'status':'false','message':message})
Belter

25

Depuis Django 1.7, vous disposez d'une JsonResponse standard, c'est exactement ce dont vous avez besoin:

from django.http import JsonResponse
...
return JsonResponse(array_to_js, safe=False)

Vous n'avez même pas besoin de json.dump votre tableau.


16
from django.http import HttpResponse
import json

class JsonResponse(HttpResponse):
    def __init__(self, content={}, mimetype=None, status=None,
             content_type='application/json'):
        super(JsonResponse, self).__init__(json.dumps(content), mimetype=mimetype,
                                           status=status, content_type=content_type)

Et dans la vue:

resp_data = {'my_key': 'my value',}
return JsonResponse(resp_data)

15

Pour ceux qui utilisent Django 1.7+

from django.http import JsonResponse

def your_view(request):
    json_object = {'key': "value"}
    return JsonResponse(json_object)

documents officiels


11

Vous voudrez utiliser le sérialiseur django pour vous aider avec les trucs unicode:

from django.core import serializers

json_serializer = serializers.get_serializer("json")()
    response =  json_serializer.serialize(list, ensure_ascii=False, indent=2, use_natural_keys=True)
    return HttpResponse(response, mimetype="application/json")

2
C'était ma version préférée, mais j'ai réalisé qu'elle ne mange que Django QuerySets .
patroqueeet

10

Avec les vues basées sur la classe Django, vous pouvez écrire:

from django.views import View
from django.http import JsonResponse

class JsonView(View):
    def get(self, request):
        return JsonResponse({'some': 'data'})

et avec Django-Rest-Framework, vous pouvez écrire:

from rest_framework.views import APIView
from rest_framework.response import Response

class JsonView(APIView):
    def get(self, request):
        return Response({'some': 'data'})

6

C'est très pratique avec Django version 1.7 ou supérieure car vous avez la classe JsonResponse, qui est une sous-classe de HttpResponse.

from django.http import JsonResponse
    def profile(request):
        data = {
            'name': 'Raghav',
            'location': 'India',
            'is_active': False,
            'count': 28
        }
        return JsonResponse(data)

Pour les anciennes versions de Django, vous devez utiliser un objet HttpResponse.

import json
from django.http import HttpResponse

def profile(request):
    data = {
        'name': 'Raghav',
        'location': 'India',
        'is_active': False,
        'count': 28
    }
    dump = json.dumps(data)
    return HttpResponse(dump, content_type='application/json')

6

Comment utiliser le moteur d'application Google avec Ajax (JSON)?

Code Javascript avec JQuery:

$.ajax({
    url: '/ajax',
    dataType : 'json',
    cache: false,
    success: function(data) {
        alert('Load was performed.'+data.ajax_resp);
    }
});

Code Python

class Ajax(webapp2.RequestHandler):
    def get(self):
        my_response = {'ajax_resp':'Hello, webapp World!'}
        datos = json.dumps(my_response)

        self.response.headers.add_header('content-type', 'application/json', charset='utf-8')
        self.response.out.write(datos)

4

Ceci est ma version préférée utilisant une vue basée sur une classe. Il suffit de sous-classer la vue de base et de remplacer la méthode get ().

import json

class MyJsonView(View):

    def get(self, *args, **kwargs):
        resp = {'my_key': 'my value',}
        return HttpResponse(json.dumps(resp), mimetype="application/json" )

4

Code Django views.py:

def view(request):
    if request.method == 'POST':
        print request.body
        data = request.body
        return HttpResponse(json.dumps(data))

Code HTML 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>
    {{data}}
    <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>

4

Importez d'abord ceci:

from django.http import HttpResponse

Si vous avez déjà le JSON:

def your_method(request):
    your_json = [{'key1': value, 'key2': value}]
    return HttpResponse(your_json, 'application/json')

Si vous obtenez le JSON d'une autre requête HTTP:

def your_method(request):
    response = request.get('https://www.example.com/get/json')
    return HttpResponse(response, 'application/json')


1

Dans View, utilisez ceci:

form.field.errors|striptags

pour obtenir des messages de validation sans html

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.