这与此问题有关: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')
答案 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包含许多不同的元素。