如何在不使用Django模板的情况下返回JSON?

时间:2012-02-13 14:36:20

标签: python json django django-views

这与此问题有关:Django return json and html depending on client python


我有一个Django应用程序的命令行Python API。当我通过API访问应用程序时,它应该返回JSON,并且使用浏览器它应该返回HTML。我可以使用不同的URL来访问不同的版本,但如何使用一个模板在 views.py 中呈现HTML模板和JSON?

要呈现我将使用的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 个答案:

答案 0 :(得分:121)

我认为这个问题已经与你想要的东西混淆了。我想你实际上并没有尝试将HTML放在JSON响应中,而是想要返回HTML或JSON。

首先,您需要了解两者之间的核心差异。 HTML是一种表现形式。它更多地涉及如何显示数据而不是数据本身。 JSON正好相反。它是纯数据 - 基本上是您拥有的某些Python(在本例中)数据集的JavaScript表示。它仅用作交换层,允许您将数据从应用程序的一个区域(视图)移动到应用程序的另一个区域(您的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')

[编辑]在Django 1.6及更早版本中,返回响应的代码是

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

答案 1 :(得分:88)

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

答案 2 :(得分:8)

在JSON响应的情况下,没有要呈现的模板。模板用于生成HTML响应。 JSON是HTTP响应。

但是,您可以使用带有JSON响应的模板呈现HTML。

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

答案 3 :(得分:7)

看起来Django REST框架在请求中使用HTTP接受标头,以便自动确定要使用的渲染器:

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

使用HTTP接受标头可能为您的“if something”提供替代来源。

答案 4 :(得分:6)

为了在django 1.9中使用JSON渲染我的模型,我必须在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')

答案 5 :(得分:2)

您还可以检查rfc中指定的请求接受内容类型。通过这种方式,您可以默认呈现HTML,并且客户端接受应用程序/ jason,您可以在响应中返回json,而无需模板

答案 6 :(得分:2)

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

答案 7 :(得分:1)

这是我根据请求的# 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) 标头有条件地呈现json或html所需的示例

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

您可以使用curl或httpie

进行测试
JsonReponse

请注意,我选择不使用Cast<>(),因为这样会不必要地使用reserialize the model

答案 8 :(得分:0)

如果要将结果作为渲染模板传递,则必须加载并渲染模板,将渲染结果传递给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包含许多不同的元素。