Django voir le retour de json sans utiliser le modèle

cela se rapportait à cette question: Django retourner json et html selon le client python

j'ai une api python en ligne de commande pour une application django. Lorsque j'accède à l'application par le biais de l'api, il doit retourner json et avec un navigateur, il doit retourner html. Je peux utiliser des urls différentes pour accéder aux différentes versions, mais comment rendre le modèle html et json dans le views.py avec un seul modèle?

pour rendre le html J'utiliserais:

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

mais comment ferais-je la même chose pour json sans mettre un modèle json? (le type de contenu doit être application/json au lieu de text / html)

Edit 1:

Qu'est-ce qui déterminerait les sorties JSON et html?

Donc, à mon point de vue:

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

Merci

63
demandé sur Community 2012-02-13 18:36:19

9 réponses

je pense que la question est devenue confuse en ce qui concerne ce que vous voulez. J'imagine que vous n'êtes pas en train d'essayer de mettre le HTML dans la réponse JSON, mais plutôt que vous voulez retourner soit HTML soit JSON.

tout d'Abord, vous devez comprendre la différence essentielle entre les deux. HTML est un format de présentation. Il traite plus de la façon d'Afficher des données que les données elles-mêmes. JSON est le contraire. Ce sont des données pures -- essentiellement une représentation JavaScript D'un certain Python (dans ce cas) dataset que vous avez. Il sert simplement à un échange de couche, vous permettant de déplacer des données d'une zone de votre application (la vue) à une autre zone de votre application (votre JavaScript) qui n'ont normalement pas accès aux autres.

avec cela à l'Esprit, vous ne" rendrez " pas JSON, et il n'y a pas de gabarits impliqués. Vous convertissez simplement toutes les données qui sont en jeu (très probablement à peu près ce que vous passez comme contexte à votre modèle) à JSON. Ce qui peut être fait, soit par La bibliothèque JSON de Django (simplejson), si c'est des données freeform, ou son framework de sérialisation, si c'est un queryset.

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)

Sérialisation

from django.core import serializers

foos = Foo.objects.all()

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

dans tous les cas, vous passez ces données dans la réponse:

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

[Modifier] Dans Django 1.6 et versions antérieures, le code de retour de la réponse a été

return HttpResponse(data, mimetype='application/json')
116
répondu Chris Pratt 2015-10-22 13:45:17

à Django 1.7 c'est encore plus facile avec le jsonresponse intégré.

https://docs.djangoproject.com/en/dev/ref/request-response/#jsonresponse-objects

# import it
from django.http import JsonResponse

def my_view(request):

    # do something with the your data
    data = {}

    # just return a JsonResponse
    return JsonResponse(data)
78
répondu davegaeddert 2014-11-04 02:43:28

dans le cas de la réponse JSON, il n'y a pas de modèle à rendre. Les modèles sont pour générer des réponses HTML. Le JSON est la réponse HTTP.

cependant, vous pouvez avoir du HTML qui est rendu à partir d'un modèle avec votre réponse JSON.

html = render_to_string("some.html", some_dictionary)
serialized_data = simplejson.dumps({"html": html})
return HttpResponse(serialized_data, mimetype="application/json")
7
répondu Uku Loskit 2012-02-13 14:49:21

il semble que le cadre REST de Django utilise L'en-tête HTTP accept dans une requête afin de déterminer automatiquement quel renderer utiliser:

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

utilisant L'en-tête HTTP accept peut fournir une source alternative pour votre"si quelque chose".

7
répondu Charles Brandt 2015-07-19 12:47:00

pour rendre mes modèles en JSON à django 1.9 j'ai dû faire ce qui suit dans mon 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')
5
répondu Raptor 2016-06-13 23:55:04

vous pouvez également vérifier le type de contenu accept request spécifié dans le rfc. De cette façon, vous pouvez rendre par défaut HTML et où votre client accepte application/jason vous pouvez retourner json dans votre réponse sans qu'un modèle soit requis

2
répondu Greg 2012-02-14 18:43:51
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')
1
répondu user3654231 2014-05-19 21:03:12

si vous voulez passer le résultat en tant que template Rendu, vous devez charger et rendre un template, passer le résultat du rendu au json.Cela pourrait ressembler à cela:

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 cette façon, vous pouvez passer un template rendu comme json à votre client. Cela peut être utile si vous souhaitez remplacer complètement ie. un contenant de nombreux éléments différents.

0
répondu marue 2012-02-13 14:44:33

voici un exemple dont j'avais besoin pour rendre JSON ou html en fonction de l'en-tête Accept de la requête"

# myapp/views.py
from django.core import serializers                                                                                
from django.http import HttpResponse                                                                                  
from django.shortcuts import render                                                                                   
from .models import Event

def event_index(request):                                                                                             
    event_list = Event.objects.all()                                                                                  
    if request.META['HTTP_ACCEPT'] == 'application/json':                                                             
        response = serializers.serialize('json', event_list)                                                          
        return HttpResponse(response, content_type='application/json')                                                
    else:                                                                                                             
        context = {'event_list': event_list}                                                                          
        return render(request, 'polls/event_list.html', context)

vous pouvez le tester avec curl ou httpie

$ http localhost:8000/event/
$ http localhost:8000/event/ Accept:application/json

note, j'ai choisi de ne pas utiliser JsonReponse qu'il aurait reserialize le modèle inutilement.

0
répondu Harry Moreno 2018-06-27 19:05:08