2012-02-13 15 views
54

Điều này liên quan đến câu hỏi này: Django return json and html depending on client pythonChế độ xem Django trở về json mà không sử dụng mẫu

Tôi có dòng lệnh trăn api cho ứng dụng django. Khi tôi truy cập các ứng dụng thông qua api nó sẽ trở lại json và với một trình duyệt nó sẽ trả về html. Tôi có thể sử dụng các url khác nhau để truy cập các phiên bản khác nhau nhưng làm cách nào để hiển thị mẫu html và json trong views.py chỉ với một mẫu?

Để render html Tôi sẽ sử dụng:

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

Nhưng làm thế nào tôi sẽ làm tương tự cho json mà không đặt một mẫu json? (Các content-type nên application/json thay vì văn bản/html)

Sửa 1:

gì sẽ quyết định kết quả đầu ra json và html?

Vì vậy, trong quan điểm của tôi:

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

Cảm ơn bạn

+0

Bạn không đọc trả lời của tôi? – Marcin

+0

@Marcin Bạn về cơ bản đã nói với anh ấy "Không, đừng làm theo cách này" mà không hiển thị cho anh ta một ví dụ về đúng cách. Đó là điều này dường như là ... – Izkata

+0

@ Jimmy, nếu đó là những gì đã xảy ra, bạn không nên chấp nhận câu trả lời của Marcin về câu hỏi khác quá nhanh. Đợi ít nhất một ngày, ai đó có thể sẽ trả lời bằng một cái gì đó giống như câu trả lời của Uku Loskit – Izkata

Trả lời

107

Tôi nghĩ rằng vấn đề đã bị nhầm lẫn về những gì bạn muốn. Tôi tưởng tượng bạn không thực sự cố gắng đặt HTML trong phản hồi JSON, nhưng thay vào đó bạn muốn trả về HTML hoặc JSON.

Trước tiên, bạn cần hiểu sự khác biệt cốt lõi giữa hai yếu tố này. HTML là một định dạng hiện tại. Nó đề cập nhiều hơn đến cách hiển thị dữ liệu hơn chính dữ liệu. JSON là ngược lại. Đó là dữ liệu thuần túy - về cơ bản là biểu diễn JavaScript của một số tập dữ liệu Python (trong trường hợp này) mà bạn có. Nó chỉ phục vụ như một lớp trao đổi, cho phép bạn di chuyển dữ liệu từ một khu vực ứng dụng của bạn (dạng xem) sang một khu vực khác của ứng dụng của bạn (JavaScript của bạn) mà thông thường không có quyền truy cập lẫn nhau.

Với ý nghĩ đó, bạn không "hiển thị" JSON và không có mẫu liên quan. Bạn chỉ đơn thuần chuyển đổi bất kỳ dữ liệu nào đang được phát (có khả năng hầu hết những gì bạn đang chuyển qua dưới dạng ngữ cảnh cho mẫu của bạn) thành JSON. Điều này có thể được thực hiện thông qua thư viện JSON của Django (simplejson), nếu đó là dữ liệu dạng tự do, hoặc khung tuần tự hóa của nó, nếu đó là một 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) 

serialization

from django.core import serializers 

foos = Foo.objects.all() 

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

Dù bằng cách nào, bạn sau đó vượt qua dữ liệu đó vào phản ứng:

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

[Chỉnh sửa] Trong Django 1.6 và ea rlier, mã trả về phản hồi là

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

Cảm ơn bạn để làm rõ. Làm cách nào để xác định trong quan điểm của tôi rằng yêu cầu phản hồi là do api cho json? Xem chỉnh sửa về câu hỏi. – Neeran

+1

Bạn có thể sử dụng 'request.is_ajax()'. Nhưng điều đó yêu cầu phải đặt tiêu đề 'HTTP_X_REQUESTED_WITH'. Hầu hết các thư viện JavaScript tự động thực hiện việc này, nhưng nếu bạn đang sử dụng một số loại ứng dụng khách khác, bạn sẽ cần đảm bảo rằng nó cũng đặt nó. Ngoài ra, bạn có thể vượt qua một chuỗi truy vấn như '? Json' với URL và sau đó kiểm tra' request.GET.has_key ('json') ', có thể dễ dàng hơn một chút. –

+14

Lưu ý rằng simplejson hiện được coi là [không được chấp nhận bởi Django 1.5] (https://docs.djangoproject.com/en/dev/releases/1.5/#system-version-of-simplejson-no-longer-used). Sử dụng 'nhập json; json.dumps (dữ liệu) 'thay thế. – Yonatan

7

Trong trường hợp phản ứng JSON không có mẫu để được trả lại. Các mẫu để tạo ra các phản hồi HTML. JSON là phản hồi HTTP.

Tuy nhiên, bạn có thể có HTML được hiển thị từ mẫu có phản hồi JSON của bạn.

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

Tôi có phải tuần tự hóa các đối tượng trước không? – Neeran

+0

simplejson.dumps() là serialization. –

0

Nếu bạn muốn vượt qua kết quả làm mẫu render bạn phải tải và đưa ra một mẫu, vượt qua kết quả của render nó vào json.This có thể nhìn như thế:

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) 

Bằng cách đó, bạn có thể chuyển một mẫu được hiển thị dưới dạng json tới máy khách của bạn. Điều này có thể hữu ích nếu bạn muốn thay thế hoàn toàn tức là. chứa rất nhiều yếu tố khác nhau.

+1

Là một lưu ý phụ, 'render_to_string' là một phím tắt cho dòng chữ" "hiển thị mẫu", và đã tồn tại kể từ Django 1.0 – Izkata

+0

Một điểm đó, bạn cũng có thể sử dụng XML thay vì JSON cho giao thoa ... – jpaugh

2

Bạn cũng có thể kiểm tra yêu cầu chấp nhận loại nội dung như được chỉ định trong rfc. Bằng cách đó bạn có thể hiển thị bằng HTML mặc định và nơi ứng dụng của bạn chấp nhận ứng dụng/jason, bạn có thể trả về json trong phản hồi của bạn mà không cần mẫu yêu cầu

7

Dường như khung công tác REST của Django sử dụng tiêu đề chấp nhận HTTP trong Yêu cầu để tự động xác định renderer để sử dụng:

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

sử dụng HTTP chấp nhận tiêu đề có thể cung cấp một nguồn thay thế cho bạn "nếu một cái gì đó".

+0

Liên kết bị hỏng. – Ajoy

+1

Cảm ơn ... vừa cập nhật nó. –

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

Đối với render mô hình của tôi trong JSON trong django 1,9 tôi phải làm như sau trong views.py tôi:

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') 
Các vấn đề liên quan