web-dev-qa-db-fra.com

Comment renvoyer JSON sans utiliser de modèle dans Django?

Ceci est lié à cette question: Django retourne json et html en fonction du client python


J'ai une ligne de commande Python API pour une Django. Lorsque j'accède à l'application via l'API, elle doit renvoyer JSON et avec un navigateur, elle doit renvoyer HTML Je peux utiliser différentes URL pour accéder aux différentes versions, mais comment puis-je restituer le modèle HTML et le code JSON dans le views.py avec un seul modèle?

Pour rendre le code 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 content-type devrait être application/json au lieu de text/html)

Que détermineraient les sorties JSON et HTML?

Donc dans my views.py :

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

Je pense que la question est devenue confuse quant à ce que vous voulez. J'imagine que vous n'essayez pas réellement de placer le code HTML dans la réponse JSON, mais plutôt de renvoyer le code HTML ou le code JSON.

Premièrement, vous devez comprendre la différence fondamentale entre les deux. HTML est un format de présentation. Il traite plus de la façon d'afficher les données que les données elles-mêmes. JSON est le contraire. Il s’agit de données pures - il s’agit essentiellement d’une représentation JavaScript de certains de vos ensembles de données Python (dans ce cas). Elles servent simplement de couche d’échange, ce qui vous permet de déplacer les données d’une zone de votre application ( la vue) vers une autre zone de votre application (votre JavaScript) qui n’a normalement pas accès les uns aux autres.

En gardant cela à l'esprit, vous ne "rendez" pas JSON, et aucun modèle n'est impliqué. Vous convertissez simplement les données en jeu (très probablement ce que vous transmettez comme contexte à votre modèle) en JSON. Ce qui peut être fait via la bibliothèque JSON de Django (simplejson), s’il s’agit de données freeform, ou son framework de sérialisation, s’il s’agit d’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)

Quoi qu'il en soit, vous transmettez ensuite ces données à la réponse:

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

[Edit] Dans Django 1.6 et versions antérieures, le code pour renvoyer la réponse était

return HttpResponse(data, mimetype='application/json')
123
Chris Pratt

Dans Django 1.7, cela est encore plus facile avec 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)
90
davegaeddert

Dans le cas de la réponse JSON, aucun modèle ne doit être rendu. Les modèles servent à générer des réponses HTML. Le JSON est la réponse HTTP.

Cependant, vous pouvez obtenir du code HTML 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")
8
Uku Loskit

Il semble que le framework Django REST utilise l'en-tête HTTP accept dans une requête afin de déterminer automatiquement le rendu à utiliser:

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

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

7
Charles Brandt

Pour rendre mes modèles au format JSON dans Django 1.9, je devais effectuer les opérations suivantes 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')
7
Raptor

Vous pouvez également vérifier que le type de contenu accepté par la demande est spécifié dans la RFC. De cette façon, vous pouvez générer un rendu HTML par défaut et, lorsque votre client accepte application/jason, vous pouvez renvoyer json dans votre réponse sans qu'un modèle ne soit nécessaire.

2
Greg
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')
2
user3654231

Voici un exemple dont j'avais besoin pour le rendu conditionnel de json ou de html en fonction de l'en-tête de la demande Accept

# 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 comme cela le ferait resérialiser le modèle inutilement.

1
Harry Moreno

Si vous voulez transmettre le résultat en tant que modèle de rendu, vous devez charger et rendre un modèle, transmettez 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 transmettre un modèle de rendu en json à votre client. Cela peut être utile si vous voulez remplacer complètement ie. un contenant beaucoup d'éléments différents.

0
marue