2012-02-13 14 views
54

Esta relacionado con esta pregunta: Django return json and html depending on client pythonvista de Django volver JSON sin utilizar la plantilla

que tienen una API de Python línea de comandos para una aplicación de Django. Cuando accedo a la aplicación a través de la API, debe devolver json y con un navegador debe devolver html. Puedo usar diferentes URL para acceder a las diferentes versiones, pero ¿cómo puedo renderizar la plantilla html y json en views.py con solo una plantilla?

Para hacer que el html yo usaría:

return render_to_response('sample/sample.html....) 

Pero ¿cómo iba a hacer lo mismo para JSON sin poner una plantilla JSON? (El tipo de contenido debe ser application/json en lugar de texto/html)

Edición 1:

Lo que determinaría las salidas JSON y html?

Así que en mis puntos de vista:

if something: 
     return render_to_response('html_template',.....) 
else: 
     return HttpReponse(jsondata,mimetype='application/json') 

Gracias

+0

¿No leyeron mi respuesta? – Marcin

+0

@Marcin Básicamente le dijiste "No, no lo hagas de esta manera" sin mostrarle un ejemplo de la manera correcta. Para eso parece ser esto ... – Izkata

+0

@Jimmy, si eso es lo que pasó, no deberías haber aceptado la respuesta de Marcin sobre la otra pregunta tan rápido. Espera al menos un día, alguien probablemente habría respondido con algo como la respuesta de Uku Loskit – Izkata

Respuesta

107

Creo que el problema se ha confundido con respecto a lo que desea. Imagino que en realidad no intenta poner el HTML en la respuesta JSON, sino que desea devolver alternativamente HTML o JSON.

En primer lugar, debe comprender la diferencia principal entre los dos. HTML es un formato de presentación. Se trata más de cómo mostrar los datos que los datos en sí. JSON es lo opuesto. Son datos puros, básicamente una representación de JavaScript de algún conjunto de datos de Python (en este caso). Sirve simplemente como una capa de intercambio, lo que le permite mover datos de un área de su aplicación (la vista) a otra área de su aplicación (su JavaScript) que normalmente no tienen acceso entre sí.

Con esto en mente, no "renderiza" JSON, y no hay plantillas involucradas. Simplemente convierte cualquier información que esté en juego (probablemente más o menos lo que está pasando como el contexto de su plantilla) en JSON. Lo cual se puede hacer a través de la biblioteca JSON de Django (simplejson), si se trata de datos de forma libre, o su marco de serialización, si se trata de un conjunto de consulta.

simplejson

from django.utils import simplejson 

some_data_to_dump = { 
    'some_var_1': 'foo', 
    'some_var_2': 'bar', 
} 

data = simplejson.dumps(some_data_to_dump) 

serialización

from django.core import serializers 

foos = Foo.objects.all() 

data = serializers.serialize('json', foos) 

De cualquier manera, a continuación, pasar esos datos en la respuesta:

return HttpResponse(data, content_type='application/json') 

[Editar] En Django 1.6 y ea Anteriormente, el código para devolver la respuesta era

return HttpResponse(data, mimetype='application/json') 
+0

Gracias usted para una aclaración. ¿Cómo determino en mi opinión que la solicitud de respuesta es por la API del json? Ver edición en la pregunta. – Neeran

+1

Puede usar 'request.is_ajax()'. Pero eso requiere que se establezca el encabezado 'HTTP_X_REQUESTED_WITH'. La mayoría de las bibliotecas de JavaScript lo hacen automáticamente, pero si está utilizando otro tipo de cliente, deberá asegurarse de que también lo establezca. Alternativamente, puede pasar una cadena de consulta como '? Json' con la URL y luego marcar' request.GET.has_key ('json') ', que probablemente sea un poco más infalible. –

+14

Tenga en cuenta que simplejson ahora se considera [obsoleto por Django 1.5] (https://docs.djangoproject.com/en/dev/releases/1.5/#system-version-of-simplejson-no-longer-used). Use 'import json; json.dumps (data) 'en su lugar. – Yonatan

7

En el caso de la respuesta JSON no hay plantilla para ser prestados. Las plantillas son para generar respuestas HTML. El JSON es la respuesta HTTP.

Sin embargo, puede tener HTML que se represente desde una plantilla dentro de su respuesta JSON.

html = render_to_string("some.html", some_dictionary) 
serialized_data = simplejson.dumps({"html": html}) 
return HttpResponse(serialized_data, mimetype="application/json") 
+0

¿Debo serializar los objetos primero? – Neeran

+0

simplejson.dumps() es lo que hace la serialización. –

0

Si desea pasar el resultado como plantilla prestado tiene que cargar y reproducir una plantilla, pasar el resultado de hacerla a los json.This podría parecerse a lo siguiente:

from django.template import loader, RequestContext 

#render the template 
t=loader.get_template('sample/sample.html') 
context=RequestContext() 
html=t.render(context) 

#create the json 
result={'html_result':html) 
json = simplejson.dumps(result) 

return HttpResponse(json) 

De esta forma, puede pasar una plantilla renderizada como json a su cliente. Esto puede ser útil si quiere reemplazar por completo, es decir. a contiene muchos elementos diferentes

+1

Como nota al margen, 'render_to_string' es un atajo para las 3 líneas" render the template ", y ha existido desde Django 1.0 – Izkata

+0

Un punto, también puede usar XML en lugar de JSON para el intercambio ... – jpaugh

2

También se podía verificar que la solicitud aceptara el tipo de contenido como se especifica en el rfc. De esta forma, puede representar por defecto HTML y cuando su cliente acepte application/jason puede devolver json en su respuesta sin necesidad de plantilla

7

Parece que el marco Django REST utiliza el encabezado HTTP accept en una solicitud para determinar automáticamente qué procesador de empleo:

http://www.django-rest-framework.org/api-guide/renderers/

Utilizando el encabezado HTTP Accept puede proporcionar una fuente alternativa para su "si algo".

+0

El enlace está roto. – Ajoy

+1

Gracias ... simplemente lo actualicé. –

1
from django.utils import simplejson 
from django.core import serializers 

def pagina_json(request): 
    misdatos = misdatos.objects.all() 
    data = serializers.serialize('json', misdatos) 
    return HttpResponse(data, mimetype='application/json') 
4

para la prestación de mis modelos en JSON en Django 1.9 que tenía que hacer lo siguiente en mi views.py:

from django.core import serializers 
from django.http import HttpResponse 
from .models import Mymodel 

def index(request): 
    objs = Mymodel.objects.all() 
    jsondata = serializers.serialize('json', objs) 
    return HttpResponse(jsondata, content_type='application/json') 
Cuestiones relacionadas