Как вернуть JSON без использования шаблона в Django?
Это связано с этим вопросом: Django возвращает json и html в зависимости от клиентского питона
У меня есть командная строка Python API для приложения Django. Когда я получаю доступ к приложению через API, оно должно возвращать JSON, а в браузере - HTML. Я могу использовать разные URL-адреса для доступа к разным версиям, но как мне отобразить HTML-шаблон и JSON в views.py только с одним шаблоном?
Для рендеринга HTML я бы использовал:
return render_to_response('sample/sample.html....')
Но как бы я сделал то же самое для JSON, не помещая шаблон JSON? (content-type
должен быть application/json
вместо text/html
)
Что будет определять выходные данные JSON и HTML?
Так в моих views.py:
if something:
return render_to_response('html_template',.....)
else:
return HttpReponse(jsondata,mimetype='application/json')
Ответы
Ответ 1
Я думаю, что проблема запуталась в том, что вы хотите. Я предполагаю, что вы на самом деле не пытаетесь поместить HTML в ответ JSON, а хотите вместо этого вернуть либо HTML, либо JSON.
Во-первых, вам нужно понять основное различие между ними. HTML - это презентационный формат. В нем больше говорится о том, как отображать данные, чем сами данные. JSON - это обратное. Это чистые данные - в основном, представление JavaScript некоторого набора данных Python (в данном случае). Он служит лишь слоем обмена, позволяя перемещать данные из одной области вашего приложения (вид) в другую область вашего приложения (ваш JavaScript), который обычно не имеет доступа друг к другу.
С учетом этого вы не "визуализируете" JSON, и там нет шаблонов. Вы просто конвертируете любые данные в игру (скорее всего, в значительной степени то, что вы передаете как контекст вашему шаблону) в JSON. Это может быть сделано через Django JSON-библиотеку (simplejson), если это данные произвольной формы или ее структура сериализации, если это запрос.
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)
Сериализация
from django.core import serializers
foos = Foo.objects.all()
data = serializers.serialize('json', foos)
В любом случае вы передаете эти данные в ответ:
return HttpResponse(data, content_type='application/json')
[Edit] В Django 1.6 и более ранних версиях код для ответа был
return HttpResponse(data, mimetype='application/json')
Ответ 2
В Django 1.7 это еще проще со встроенным JsonResponse.
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)
Ответ 3
В случае ответа JSON нет шаблона для визуализации. Шаблоны предназначены для генерации ответов HTML. JSON является ответом HTTP.
Однако вы можете иметь HTML, который отображается из шаблона с ответом вашего JSON.
html = render_to_string("some.html", some_dictionary)
serialized_data = simplejson.dumps({"html": html})
return HttpResponse(serialized_data, mimetype="application/json")
Ответ 4
Похоже, что среда Django REST использует заголовок Accept Accept в запросе, чтобы автоматически определить, какой рендер использовать:
http://www.django-rest-framework.org/api-guide/renderers/
Использование заголовка Accept HTTP может предоставить альтернативный источник для вашего "если что-то".
Ответ 5
Для рендеринга моих моделей в JSON в django 1.9 мне нужно было сделать следующее в моих 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')
Ответ 6
Вы также можете проверить тип содержимого запроса, как указано в rfc. Таким образом, вы можете отображать по умолчанию HTML и где ваш клиент принимает приложение /jason, вы можете вернуть json в свой ответ без требуемого шаблона
Ответ 7
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')
Ответ 8
Вот пример, который мне нужен для условного рендеринга json или html в зависимости от заголовка Request 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)
Вы можете проверить это с помощью curl или httpie
$ http localhost:8000/event/
$ http localhost:8000/event/ Accept:application/json
Обратите внимание, что я решил не использовать JsonReponse
как это излишне повторно сериализует модель.
Ответ 9
Если вы хотите передать результат в качестве визуализированного шаблона, вам нужно загрузить и отобразить шаблон, передать результат его рендеринга в json. Это может выглядеть так:
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)
Таким образом, вы можете передать обработанный шаблон json вашему клиенту. Это может быть полезно, если вы хотите полностью заменить ie. a содержит множество различных элементов.