web-dev-qa-db-ja.com

Djangoでテンプレートを使用せずにJSONを返すにはどうすればよいですか?

これはこの質問に関連しています: DjangoはクライアントPythonに応じてjsonとhtmlを返します


Pythonアプリ用のコマンドラインDjango AP​​Iがあります。 APIを介してアプリにアクセスすると、JSONが返され、ブラウザーではHTMLが返されます。異なるURLを使用して異なるバージョンにアクセスできますが、1つのテンプレートだけでviews.pyでHTMLテンプレートとJSONをレンダリングするにはどうすればよいですか?

HTMLをレンダリングするには、次を使用します。

return render_to_response('sample/sample.html....')

しかし、JSONテンプレートを配置せずにJSONで同じことを行うにはどうすればよいですか? (content-typeapplication/jsonではなくtext/htmlでなければなりません)

JSONおよびHTML出力を決定するものは何ですか?

だから私のviews.py

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

私はあなたが望むものに関して問題が混乱していると思います。あなたが実際にJSON応答にHTMLを入れようとしているのではなく、代わりにHTMLまたはJSONのどちらかを返したいと思っています。

最初に、2つのコアの違いを理解する必要があります。 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')
123
Chris Pratt

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)
90
davegaeddert

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")
8
Uku Loskit

Django RESTフレームワークは、使用するレンダラーを自動的に決定するために、リクエストでHTTP acceptヘッダーを使用するように見えます。

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

HTTP Acceptヘッダーを使用すると、「if if」の代替ソースが提供される場合があります。

7
Charles Brandt

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

また、rfcで指定されているコンテンツタイプを受け入れるリクエストを確認することもできます。そうすれば、デフォルトのHTMLでレンダリングでき、クライアントがアプリケーション/ジェイソンを受け入れる場合、テンプレートを必要とせずに応答でjsonを返すことができます

2
Greg
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
user3654231

以下は、リクエストの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または httpie でテストできます

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

注:JsonReponseを使用しないことを選択しました モデルの再シリアル化 不必要に。

1
Harry Moreno

結果をレンダリングされたテンプレートとして渡したい場合、テンプレートをロードしてレンダリングする必要があり、レンダリング結果を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としてクライアントに渡すことができます。これは、完全に置き換える場合などに役立ちます。さまざまな要素がたくさん含まれています。

0
marue