Crear una respuesta JSON usando Django y Python

452

Estoy tratando de convertir un script de respuesta Ajax del lado del servidor en Django HttpResponse, pero aparentemente no funciona.

Este es el script del lado del servidor:

/* 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.
        }
    }
}

Y este es el código convertido

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

Estoy usando simplejson para codificar la lista de Python (por lo que devolverá una matriz JSON). No pude resolver el problema todavía. Pero creo que hice algo mal con el 'eco'.

Cambiar
fuente
También puede usar el decorador de vistas molesto de django @ajax_request.
zopieux

Respuestas:

917

Usualmente uso un diccionario, no una lista para devolver contenido JSON.

import json

from django.http import HttpResponse

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

Pre-Django 1.7 lo devolverías así:

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

Para Django 1.7+, use JsonResponsecomo se muestra en esta respuesta SO así:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})
Tom
fuente
44
Que es el tipo MIME, no la lista que debe ser él metiendo en problemas. Mientras que la mayoría de JSON es típicamente un objeto ("diccionario") en el nivel superior, JSON está perfectamente satisfecho con una matriz en el nivel superior.
Thanatos
66
Lo siento, no está claro por lo que escribí, pero solo quise decir que uso un diccionario porque es más limpio / fácil cuando lo serializo a JSON.
Tom
'application / json' no se admite correctamente en versiones anteriores de IE. Aquí hay una discusión sobre el tema github.com/blueimp/jQuery-File-Upload/issues/123
Victoria
161

Nuevo en django 1.7

podrías usar objetos JsonResponse .

de los documentos:

from django.http import JsonResponse
return JsonResponse({'foo':'bar'})
srj
fuente
2
Una desventaja: su valor predeterminado es ensure_asciiy todavía no he encontrado una manera de anularlo. Creé una nueva pregunta para esto: stackoverflow.com/q/34798703/854477
int_ua
@int_ua: solo agregue json_dumps_params={"ensure_ascii": False}(requiere Django 1.9 o más reciente)
Martijn Pieters
139

Yo uso esto, funciona 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')

Alternativa:

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

En Django 1.7 , se han agregado objetos JsonResponse al propio marco de Django, lo que hace que esta tarea sea aún más fácil:

from django.http import JsonResponse
def some_view(request):
    return JsonResponse({"key": "value"})
Dingo
fuente
1
El problema es que no obtiene el valor del campo de entrada vld_value = request.POST.get ('validateValue')
Cambie el
2
Con Python 2.7, debería ser "import json"
Cullen Fluffy Jennings
1
Creo que from django.utils import simplejsones por compatibilidad con versiones anteriores.
Skylar Saveland
JsonResponse(status=404, data={'status':'false','message':message})
Belter
25

Desde Django 1.7 tienes un JsonResponse estándar que es exactamente lo que necesitas:

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

Ni siquiera necesita json.dump su matriz.

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

Y a la vista:

resp_data = {'my_key': 'my value',}
return JsonResponse(resp_data)
Dmitry Demidenko
fuente
15

Para aquellos que usan Django 1.7+

from django.http import JsonResponse

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

documentos oficiales

Andres
fuente
11

Querrá usar el serializador de django para ayudar con cosas 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")
ReduxDJ
fuente
2
Esta era mi versión preferida, pero me di cuenta de que solo come Django QuerySets .
patroqueeet
10

Con las vistas basadas en Django Class puedes escribir:

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

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

y con Django-Rest-Framework puedes escribir:

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

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

Es muy conveniente con Django versión 1.7 o superior, ya que tiene la clase JsonResponse, que es una subclase de HttpResponse.

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

Para versiones anteriores de Django, debe usar un objeto 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')
Tanmay D
fuente
6

¿Cómo usar el motor de aplicaciones de google con ajax (json)?

Código Javascript con 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)
Samiro
fuente
4

Esta es mi versión preferida usando una vista basada en clases. Simplemente subclasifique la Vista básica y anule el método get ().

import json

class MyJsonView(View):

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

Código Django views.py:

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

Código 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>
Rajan Mandanka
fuente
4

Primero importe esto:

from django.http import HttpResponse

Si ya tienes el JSON:

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

Si obtiene el JSON de otra solicitud HTTP:

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

Utilice JsonResponse

from django.http import JsonResponse
Suraj Verma
fuente
Esta respuesta necesita contexto y explicación.
theUtherSide
1

En View usa esto:

form.field.errors|striptags

para obtener mensajes de validación sin html

Deepak Sharma
fuente