Django'da şablon kullanmadan nasıl JSON döndürürüm?


82

Bu, şu soruyla ilgilidir: Django, istemci python'a bağlı olarak json ve html döndürür


Bir Django uygulaması için Python API komut satırı kullanıyorum. Uygulamaya API aracılığıyla eriştiğimde JSON döndürmeli ve bir tarayıcıyla HTML döndürmelidir. Farklı sürümlere erişmek için farklı URL'ler kullanabilirim, ancak views.py'deki HTML şablonunu ve JSON'u tek bir şablonla nasıl oluşturabilirim?

HTML'yi oluşturmak için kullanacağım:

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

Peki JSON şablonu koymadan JSON için aynısını nasıl yaparım? ( yerine content-typeolmalıdır )application/jsontext/html

JSON ve HTML çıktılarını ne belirler?

Yani views.py'imde :

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

@Marcin Ona doğru yolu örneklemeden "Hayır, bunu bu şekilde yapma" dedin. Bunun için öyle görünüyor ...
Izkata

@ Jimmy, eğer böyle olduysa, Marcin'in diğer soruya verdiği cevabı bu kadar çabuk kabul etmemeliydin. En az bir gün bekleyin, birisi muhtemelen Uku Loskit'in cevabı gibi bir cevap
verirdi

@ İzkata: Aslında ona hangi kütüphaneyi kullanacağını söyledim. Bu soru, bir başkasının onun için kodunu yazmasını sağlamak gibi görünüyor.
Marcin

Yanıtlar:


134

Bence ne istediğinle ilgili konu karıştı. Aslında HTML'yi JSON yanıtına koymaya çalışmadığınızı, bunun yerine alternatif olarak HTML veya JSON döndürmek istediğinizi hayal ediyorum.

İlk olarak, ikisi arasındaki temel farkı anlamanız gerekir. HTML bir sunum biçimidir. Verilerin kendisinden çok verilerin nasıl görüntüleneceği ile ilgilenir. JSON bunun tam tersidir. Saf veridir - temelde sahip olduğunuz bazı Python (bu durumda) veri kümesinin JavaScript temsili. Yalnızca bir değişim katmanı görevi görerek, verileri uygulamanızın bir alanından (görünüm) uygulamanızın normalde birbirine erişimi olmayan başka bir alanına (JavaScript'iniz) taşımanıza olanak tanır.

Bunu göz önünde bulundurarak, JSON'u "oluşturmazsınız" ve ilgili şablon yoktur. Yalnızca oyunda olan verileri (büyük olasılıkla şablonunuza bağlam olarak aktardığınız şeyi) JSON'a dönüştürürsünüz. Bu, serbest biçimli veri ise Django'nun JSON kitaplığı (simplejson) veya bir sorgu kümesiyse serileştirme çerçevesi aracılığıyla yapılabilir.

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)

Serileştirme

from django.core import serializers

foos = Foo.objects.all()

data = serializers.serialize('json', foos)

Her iki durumda da, bu verileri yanıta iletirsiniz:

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

[Düzenle] Django 1.6 ve önceki sürümlerde, yanıt döndürülecek kod

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

[DÜZENLE]: simplejson django'dan kaldırıldı , şunları kullanabilirsiniz:

import json

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

Veya django.core.serializersyukarıda açıklandığı gibi kullanabilirsiniz.


Açıklama için teşekkür ederim. Görüşlerime göre yanıt isteğinin json için API tarafından yapıldığını nasıl belirleyebilirim? Soru üzerinde düzenlemeye bakın.
Neeran

1
Kullanabilirsiniz request.is_ajax(). Ancak bu, HTTP_X_REQUESTED_WITHbaşlığın ayarlanmış olmasını gerektirir . Çoğu JavaScript kitaplığı bunu otomatik olarak yapar, ancak başka türde bir istemci kullanıyorsanız, onun da ayarladığından emin olmanız gerekir. Alternatif olarak ?json, URL gibi bir sorgu dizesini iletebilir ve ardından kontrol edebilirsiniz request.GET.has_key('json'), bu muhtemelen biraz daha kusursuzdur.
Chris Pratt

18
Simplejson'un artık Django 1.5 tarafından kullanımdan kaldırıldığına dikkat edin . import json ; json.dumps(data)Bunun yerine kullanın .
Yonatan

1
OP, requestnesnedeki "Kabul Et" içerik türü görüşme başlığını kontrol etmelidir . Bakınız: w3.org/Protocols/rfc2616/rfc2616-sec14.html (büyük bir okuma parçası, ancak göstermek için basitleştirilmiş bir kod örneği kullanılabilir ve en azından esnek olmayan bir sistem yazmak çok zor olmazdı onlar soruyorsun iki vaka) işlemek
Merlyn Morgan-graham

14
Benim durumumda (Django 1.7),
mimetype


8

JSON yanıtı durumunda, işlenecek şablon yoktur. Şablonlar, HTML yanıtları oluşturmak içindir. JSON, HTTP yanıtıdır.

Ancak, JSON yanıtınızla birlikte bir şablondan oluşturulan HTML'niz olabilir.

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

Önce nesneleri serileştirmem gerekiyor mu?
Neeran

simplejson.dumps () serileştirmenin ne yaptığıdır.
Uku Loskit

teşekkür ederim kesinlikle iyi çalışıyor. Simplejson yerine json da kullanabiliriz @UkuLoskit
Chirag Kanzariya


7

Modellerimi django 1.9'da JSON'da işlemek için views.py'de aşağıdakileri yapmam gerekiyordu:

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


2

Ayrıca rfc'de belirtildiği gibi istek kabul içerik türünü kontrol edebilirsiniz. Bu şekilde, varsayılan HTML olarak render edebilirsiniz ve istemcinizin application / jason'ı kabul ettiği durumlarda, bir şablon gerekmeden yanıtınızda json'u döndürebilirsiniz


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

İsteğin Acceptbaşlığına bağlı olarak json veya html'yi koşullu olarak oluşturmak için ihtiyacım olan bir örnek.

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

bunu curl veya httpie ile test edebilirsiniz

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

Not Modeli gereksiz yere JsonReponseyeniden seri hale getireceği için kullanmamayı seçtim .


0

Sonucu oluşturulmuş bir şablon olarak geçirmek istiyorsanız, bir şablonu yüklemeniz ve işlemeniz gerekir, bunu oluşturma sonucunu json'a iletmeniz gerekir.

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)

Bu şekilde, oluşturulmuş bir şablonu müşterinize json olarak iletebilirsiniz. İe'yi tamamen değiştirmek istiyorsanız bu yararlı olabilir. çok sayıda farklı öğe içeren bir.


1
Bir yan not olarak, render_to_string3 "şablonu
oluştur
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.