Как вернуть JSON без использования шаблона в Django? - PullRequest
72 голосов
/ 13 февраля 2012

Это связано с этим вопросом: 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')

Ответы [ 9 ]

123 голосов
/ 13 февраля 2012

Я думаю, что вопрос запутался относительно того, что вы хотите.Я полагаю, что вы на самом деле не пытаетесь поместить 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')
88 голосов
/ 04 ноября 2014

В 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)
8 голосов
/ 13 февраля 2012

В случае ответа 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")
7 голосов
/ 14 июня 2016

Для рендеринга моих моделей в 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')
7 голосов
/ 01 декабря 2012

Похоже, что среда REST Django использует в запросе заголовок HTTP accept, чтобы автоматически определить, какой рендер использовать:

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

Использование заголовка HTTP accept может предоставить альтернативный источник для вашего «если что-то».

2 голосов
/ 20 мая 2014
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 голосов
/ 14 февраля 2012

Вы также можете проверить запрос на принятие типа содержимого, как указано в rfc. Таким образом, вы можете визуализировать HTML по умолчанию, и когда ваш клиент принимает приложение / jason, вы можете вернуть json в своем ответе без использования шаблона

1 голос
/ 27 июня 2018

Вот пример, который мне нужен для условного рендеринга 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

примечание. Я решил не использовать JsonReponse, так как это приведет к повторной инициализации модели без необходимости.

0 голосов
/ 13 февраля 2012

Если вы хотите передать результат как отрендеренный шаблон, вам нужно загрузить и вывести шаблон, передайте результат рендеринга в 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 своему клиенту. Это может быть полезно, если вы хотите полностью заменить т.е. содержащий множество различных элементов.

...