Это связано с этим вопросом: Django возвращает json и html в зависимости от клиентского python
У меня есть командная строка 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')
python
json
django
django-views
Ниран
источник
источник
Ответы:
Я думаю, что проблема запуталась в том, что вы хотите. Я предполагаю, что вы на самом деле не пытаетесь поместить HTML в ответ JSON, а скорее хотите альтернативно вернуть HTML или JSON.
Во-первых, вам нужно понять основную разницу между ними. HTML - это формат представления. Он больше касается того, как отображать данные, чем сами данные. JSON - наоборот. Это чистые данные - в основном представление JavaScript некоторого набора данных Python (в данном случае), который у вас есть. Он служит просто уровнем обмена, позволяя вам перемещать данные из одной области вашего приложения (представления) в другую область вашего приложения (ваш JavaScript), которые обычно не имеют доступа друг к другу.
Имея это в виду, вы не будете «отображать» JSON, и в нем не будут задействованы шаблоны. Вы просто конвертируете все данные, которые находятся в игре (скорее всего, в значительной степени то, что вы передаете в качестве контекста в свой шаблон) в JSON. Это можно сделать либо с помощью библиотеки JSON Django (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')
[EDIT]: simplejson был удален из django , вы можете использовать:
import json json.dumps({"foo": "bar"})
Или вы можете использовать,
django.core.serializers
как описано выше.источник
request.is_ajax()
. Но для этого необходимо установитьHTTP_X_REQUESTED_WITH
заголовок. Большинство библиотек JavaScript делают это автоматически, но если вы используете какой-либо другой тип клиента, вам необходимо убедиться, что он также устанавливает его. В качестве альтернативы вы можете передать строку запроса, например,?json
с URL-адресом, а затем проверитьrequest.GET.has_key('json')
, что, вероятно, немного более надежно.import json ; json.dumps(data)
Вместо этого используйте .request
объекте. См.: W3.org/Protocols/rfc2616/rfc2616-sec14.html (большой объем чтения, но для демонстрации можно использовать упрощенный образец кода, и было бы несложно написать негибкую систему, которая хотя бы занимаются двумя делами, которые они просят)В 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)
источник
В случае ответа 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")
источник
Похоже, что структура Django REST использует заголовок принятия HTTP в запросе, чтобы автоматически определять, какой рендерер использовать:
http://www.django-rest-framework.org/api-guide/renderers/
Использование заголовка принятия HTTP может предоставить альтернативный источник для вашего «если что-то».
источник
Для рендеринга моих моделей в 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')
источник
Вы также можете проверить тип содержимого для принятия запроса, указанный в файле rfc. Таким образом, вы можете отображать HTML по умолчанию, и если ваш клиент принимает приложение / jason, вы можете вернуть json в свой ответ без необходимости шаблона
источник
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')
источник
Вот пример, который мне нужен для условного рендеринга json или html в зависимости от
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
note Я решил не использовать,
JsonReponse
поскольку это приведет к повторной сериализации модели без необходимости.источник
Если вы хотите передать результат в виде отрисованного шаблона, вам нужно загрузить и отрендерить шаблон, передайте результат отрисовки в 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, содержащий множество различных элементов.
источник
render_to_string
это ярлык для трех строк «рендеринга шаблона», который существует с Django 1.0