Django에서 템플릿을 사용하지 않고 JSON을 반환하려면 어떻게해야합니까?


81

이것은이 질문과 관련이 있습니다 : Django는 클라이언트 파이썬에 따라 json과 html을 반환합니다 .


Django 앱용 명령 줄 Python API가 있습니다. API를 통해 앱에 액세스하면 JSON을 반환해야하고 브라우저에서는 HTML을 반환해야합니다. 다른 URL을 사용하여 다른 버전에 액세스 할 수 있지만 하나의 템플릿으로 views.py 에서 HTML 템플릿과 JSON을 어떻게 렌더링 합니까?

HTML을 렌더링하려면 다음을 사용합니다.

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

하지만 JSON 템플릿을 넣지 않고 어떻게 JSON에 대해 똑같이 할 수 있습니까? ( 대신 content-type이어야 함 )application/jsontext/html

JSON 및 HTML 출력을 결정하는 것은 무엇입니까?

그래서 내 views.py에서 :

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

@Marcin 당신은 기본적으로 그에게 올바른 방법의 예를 보여주지 않고 "아니,이 방법으로하지 마십시오"라고 말했습니다. 즉 ...이 하나가 될 것으로 보인다 무엇
Izkata

@Jimmy, 그게 일어난 일이라면 다른 질문에 대한 Marcin의 대답을 너무 빨리 받아들이지 말았어야했습니다. 적어도 하루를 기다리십시오. 누군가 Uku Loskit의 대답과 같은 대답을했을 것입니다.
Izkata

@Izkata : 실제로 어떤 라이브러리를 사용할지 그에게 말 했어요. 이 질문은 다른 사람이 자신의 코드를 작성하도록하기위한 것 같습니다.
Marcin 2012

답변:


131

나는 당신이 원하는 것에 대해 문제가 혼란스러워했다고 생각합니다. 실제로 JSON 응답에 HTML을 넣으려는 것이 아니라 대신 HTML 또는 JSON을 반환하고 싶다고 생각합니다.

첫째, 둘의 핵심적인 차이점을 이해해야합니다. HTML은 프리젠 테이션 형식입니다. 데이터 자체보다 데이터를 표시하는 방법을 더 많이 다룹니다. JSON은 그 반대입니다. 순수한 데이터입니다. 기본적으로 여러분이 가지고있는 일부 Python (이 경우) 데이터 셋의 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')

[편집] : simplejson이 django 에서 제거되었습니다 . 다음을 사용할 수 있습니다.

import json

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

또는 django.core.serializers위에서 설명한대로 사용할 수 있습니다 .


설명해 주셔서 감사합니다. 응답 요청이 json에 대한 API에 의한 것인지 내 뷰에서 어떻게 결정합니까? 질문에 대한 편집을 참조하십시오.
Neeran 2012

1
사용할 수 있습니다 request.is_ajax(). 그러나 HTTP_X_REQUESTED_WITH헤더가 설정되어 있어야합니다 . 대부분의 자바 스크립트 라이브러리는이 작업을 자동으로 수행하지만 다른 유형의 클라이언트를 사용하는 경우에도 설정되어 있는지 확인해야합니다. 또는 ?jsonURL과 같은 쿼리 문자열을 전달한 다음을 확인할 수 request.GET.has_key('json')있습니다.
Chris Pratt

18
simplejson은 이제 Django 1.5에서 더 이상 사용되지 않는 것으로 간주됩니다 . import json ; json.dumps(data)대신 사용하십시오 .
Yonatan 2013

1
OP는 request개체 의 "Accept"콘텐츠 유형 협상 헤더를 확인해야 합니다. : 참조 w3.org/Protocols/rfc2616/rfc2616-sec14.html (읽기의 큰 mamoth을하지만, 단순화 된 코드 샘플을 보여주기 위해 사용할 수 있었다, 적어도 것 경직된 시스템을 작성하는 매우 어렵지 않을 것 그들이 요구하고 두 경우를) 처리
Merlyn 모건 - 그레이엄에게

14
제 경우 (Django 1.7)는 mimetype이 아닌 content_type = 'application / json'
이었습니다.


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

먼저 객체를 직렬화해야합니까?
Neeran

simplejson.dumps ()는 직렬화를 수행합니다.
Uku Loskit 2012

정말 잘 작동 해 주셔서 감사합니다. 우리는 대신 simplejson @UkuLoskit의 또한 JSON 사용할 수 있습니다
살짝 Kanzariya


7

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

당신은 사용할 수 있습니다 JsonResponse
MichielB

2

rfc에 지정된대로 요청 수락 콘텐츠 유형을 확인할 수도 있습니다. 이렇게하면 기본 HTML로 렌더링 할 수 있으며 클라이언트가 애플리케이션 / 제이슨을 수락하는 경우 템플릿 없이도 응답에 json을 반환 할 수 있습니다.


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

1

다음은 Request의 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그 것처럼 모델을 다시 일련 화 불필요.


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를 완전히 교체하려는 경우 유용 할 수 있습니다. 많은 다른 요소를 포함합니다.


1
참고로 render_to_string는 3 개의 "템플릿 렌더링"줄의 바로 가기이며 Django 1.0
Izkata
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.