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

Python 如何在不使用Django中的模板的情况下返回JSON?,python,json,django,django-views,Python,Json,Django,Django Views,这与这个问题有关: 我有一个Django应用程序的命令行Python API。当我通过API访问应用程序时,它应该返回JSON,在浏览器中它应该返回HTML。我可以使用不同的URL访问不同的版本,但是如何仅使用一个模板在views.py中呈现HTML模板和JSON 要呈现HTML,我将使用: return render_to_response('sample/sample.html....') 但是我如何在不放置JSON模板的情况下对JSON执行相同的操作呢?(内容类型应为applicati

这与这个问题有关:


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

要呈现HTML,我将使用:

return render_to_response('sample/sample.html....')
但是我如何在不放置JSON模板的情况下对JSON执行相同的操作呢?(内容类型应为
application/json
,而不是
text/html

什么将决定JSON和HTML输出

因此,在我的视图中.py

if something:
    return render_to_response('html_template',.....)
else:
    return HttpReponse(jsondata,mimetype='application/json')

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

html = render_to_string("some.html", some_dictionary)
serialized_data = simplejson.dumps({"html": html})
return HttpResponse(serialized_data, mimetype="application/json")
但是,可以使用JSON响应从模板呈现HTML

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

如果要将结果作为呈现模板传递,则必须加载并呈现模板,将呈现结果传递给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,这可能会很有用。

我认为,关于你想要什么,这个问题已经被弄糊涂了。我想您实际上并没有试图将HTML放入JSON响应中,而是希望交替返回HTML或JSON

首先,您需要了解两者之间的核心区别。HTML是一种表示格式。它处理的更多的是如何显示数据,而不是数据本身。JSON正好相反。这是纯数据——基本上是您拥有的某些Python(在本例中)数据集的JavaScript表示。它只是一个交换层,允许您将数据从应用程序的一个区域(视图)移动到应用程序的另一个区域(JavaScript),而这些区域通常互不访问

记住这一点,您不需要“呈现”JSON,也不需要模板。您只需将任何正在使用的数据(很可能是作为上下文传递给模板的数据)转换为JSON。这可以通过Django的JSON库(simplejson)(如果是自由格式数据)或其序列化框架(如果是queryset)实现

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)
序列化

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')
[编辑]:,您可以使用:

import json

json.dumps({"foo": "bar"})

或者,您可以如上所述使用
django.core.serializers

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

看起来Django REST框架在请求中使用HTTP accept标头,以便自动确定要使用的呈现程序:


在Django 1.7中,使用HTTP accept头可以为“if something”提供一个替代源。使用内置的JsonResponse,这更容易


为了在django 1.9中以JSON呈现模型,我必须在my 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')

下面是一个示例,我需要根据请求的
Accept
头有条件地呈现json或html

# 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或


注意:我选择不使用
jsonresponse
,因为这是不必要的。

我必须先序列化对象吗?simplejson.dumps()是序列化的目的。谢谢,它工作得非常好。我们也可以使用json代替simplejson@UkuLoskit@Marcin你基本上告诉他“不,不要这样做”,但没有给他一个正确方法的例子。吉米,如果真是这样的话,你不应该这么快就接受马辛对另一个问题的回答。至少等一天,可能有人会用Uku Loskit的回答answer@Izkata例如我确实告诉过他该用哪个图书馆。此问题似乎是为了让其他人为他编写代码。请注意,
render_to_string
是3行“render the template”的快捷方式,自Django 1.0以来一直存在,请澄清。如何在视图中确定响应请求是由json的api发出的?请参阅问题编辑。您可以使用
request.is\u ajax()
。但这需要设置带有头的
HTTP\u X\u REQUESTED\u。大多数JavaScript库都会自动执行此操作,但如果您使用的是其他类型的客户机,则需要确保它也设置了此功能。或者,您可以通过URL传递查询字符串,例如
?json
,然后检查
request.GET.has_key('json')
,这可能更简单。请注意,现在考虑使用simplejson。使用
导入json;而是转储(数据)
。OP应该检查
请求
对象中的“接受”内容类型协商头。请参阅:(阅读量很大,但可以使用简化的代码示例进行演示,编写一个不灵活的系统来至少处理他们提出的两种情况并不难)在我的案例(Django 1.7)中,它是content_type='application/json',而不是您可以使用的mimetype