web-dev-qa-db-de.com

Wie kann ich JSON ohne Verwendung einer Vorlage in Django zurückgeben?

Dies hängt mit dieser Frage zusammen: Django gibt je nach Client-Python json und html zurück


Ich habe eine Befehlszeile Python API für eine Django App. Wenn ich über die API auf die App zugreife, sollte sie JSON und mit einem Browser HTML zurückgeben Ich kann verschiedene URLs verwenden, um auf die verschiedenen Versionen zuzugreifen, aber wie rendere ich die HTML-Vorlage und JSON in der Datei views.py mit nur einer Vorlage?

Zum Rendern des HTML würde ich Folgendes verwenden:

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

Aber wie würde ich dasselbe für JSON tun, ohne eine JSON-Vorlage zu platzieren? (das content-type sollte sein application/json anstatt text/html)

Was würde die JSON- und HTML-Ausgabe bestimmen?

Also in meiner views.py :

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

Ich denke, das Thema ist verwirrt, was Sie wollen. Ich stelle mir vor, Sie versuchen nicht, den HTML-Code in die JSON-Antwort einzufügen, sondern möchten alternativ entweder HTML oder JSON zurückgeben.

Zuerst müssen Sie den Kernunterschied zwischen den beiden verstehen. HTML ist ein Präsentationsformat. Es geht mehr um die Anzeige von Daten als um die Daten selbst. JSON ist das Gegenteil. Es handelt sich um reine Daten - im Grunde genommen handelt es sich um eine JavaScript-Darstellung eines Python) -Datensatzes. Sie dient lediglich als Austauschschicht, mit der Sie Daten aus einem Bereich Ihrer App verschieben können ( die Ansicht) zu einem anderen Bereich Ihrer App (Ihrem JavaScript), die normalerweise keinen Zugriff aufeinander haben.

In diesem Sinne wird JSON nicht "gerendert", und es sind keine Vorlagen beteiligt. Sie konvertieren lediglich alle im Spiel befindlichen Daten (höchstwahrscheinlich das, was Sie als Kontext für Ihre Vorlage übergeben) nach JSON. Dies kann entweder über Djangos JSON-Bibliothek (simplejson) erfolgen, wenn es sich um Freiformdaten handelt, oder über das Serialisierungsframework, wenn es sich um ein Abfrageset handelt.

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)

Serialisierung

from Django.core import serializers

foos = Foo.objects.all()

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

In beiden Fällen geben Sie diese Daten an die Antwort weiter:

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

[Bearbeiten] In Django 1.6 und früher war der Code für die Antwort

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

In Django 1.7 ist dies mit der integrierten JsonResponse noch einfacher.

https://docs.djangoproject.com/de/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

Im Fall der JSON-Antwort muss keine Vorlage gerendert werden. Vorlagen dienen zum Generieren von HTML-Antworten. Der JSON ist die HTTP-Antwort.

Sie können jedoch HTML-Code verwenden, der aus einer Vorlage mit Ihrer JSON-Antwort gerendert wird.

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

Es sieht so aus, als ob das Django REST) - Framework den HTTP-Accept-Header in einer Anfrage verwendet, um automatisch zu bestimmen, welcher Renderer verwendet werden soll:

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

Die Verwendung des HTTP-Accept-Headers bietet möglicherweise eine alternative Quelle für Ihr "if something".

7
Charles Brandt

Um meine Modelle in JSON in Django 1.9 zu rendern, musste ich in meiner views.py Folgendes tun:

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

Sie können auch den im RFC angegebenen Inhaltstyp für Anforderungsannahme überprüfen. Auf diese Weise können Sie standardmäßig HTML rendern und dort, wo Ihr Client application/jason akzeptiert, json in Ihrer Antwort zurückgeben, ohne dass eine Vorlage erforderlich ist

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

Hier ist ein Beispiel, das ich für das bedingte Rendern von json oder html in Abhängigkeit vom Header Accept der Anforderung benötigt habe

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

sie können dies mit curl oder httpie testen

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

note Ich habe mich entschieden, JsonReponse nicht zu verwenden, da dies das Modell erneut serialisieren würde unnötig.

1
Harry Moreno

Wenn Sie das Ergebnis als gerenderte Vorlage übergeben möchten, müssen Sie eine Vorlage laden und rendern. Übergeben Sie das Ergebnis des Renderns an json. Dies könnte folgendermaßen aussehen:

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)

Auf diese Weise können Sie eine gerenderte Vorlage als json an Ihren Client übergeben. Dies kann nützlich sein, wenn Sie z. B. vollständig ersetzen möchten. a enthält viele verschiedene Elemente.

0
marue