2012-06-04 25 views
6

Tôi đang cố gắng để trở lại một chức năng như thế này:Tôi làm cách nào để định cấu hình mã hóa JSON của Pyramid?

@view_config(route_name='CreateNewAccount', request_method='GET', renderer='json') 
def returnJSON(color, message=None): 
    return json.dumps({ "color" : "color", "message" : "message" }, default=json_util.default) 

Bởi vì mã hóa JSON riêng Kim Tự Tháp, nó sắp ra đúp mã hóa như thế này:

"{\"color\": \"color\", \"message\": \"message\"}" 

Làm thế nào tôi có thể sửa lỗi này? Tôi cần phải sử dụng default argument (hoặc tương đương) vì nó được yêu cầu cho các loại tùy chỉnh của Mongo.

+4

Đây không phải là định dạng lạ. Đây là định dạng JSON được định dạng * bình thường *, nó sử dụng dấu ngoặc kép thoát. – VisioN

+1

@VisioN: Nó * là * định dạng JSON bình thường ... * cho chuỗi *. –

+0

Tại sao tôi không gặp lỗi nếu tôi chuyển sang JSON thẳng (không có JSON.dumps)? – zakdances

Trả lời

8

Nó có vẻ như từ điển đang được JSON-mã hóa hai lần, tương đương với:

json.dumps(json.dumps({ "color" : "color", "message" : "message" })) 

Có lẽ khuôn khổ Python của bạn tự động JSON-mã hóa kết quả? Hãy thử điều này thay vì:

def returnJSON(color, message=None): 
    return { "color" : "color", "message" : "message" } 

EDIT:

Để sử dụng một renderer Pyramid tùy chỉnh mà tạo ra JSON theo cách bạn muốn, hãy thử này (dựa trên renderer docsrenderer sources).

Trong khởi động:

from pyramid.config import Configurator 
from pyramid.renderers import JSON 

config = Configurator() 
config.add_renderer('json_with_custom_default', JSON(default=json_util.default)) 

Sau đó, bạn có một 'json_with_custom_default' renderer để sử dụng:

@view_config(route_name='CreateNewAccount', request_method='GET', renderer='json_with_custom_default') 

EDIT 2

Một lựa chọn khác có thể là để trả về một đối tượng Response mà ông renderer không nên sửa đổi. Ví dụ.

from pyramid.response import Response 
def returnJSON(color, message): 
    json_string = json.dumps({"color": color, "message": message}, default=json_util.default) 
    return Response(json_string) 
+0

Hoạt động như tôi đã đề cập trong bài đăng. Tôi cần phải sử dụng JSON.dumps mặc dù vì tôi cần mặc định = json_util.default để serialize các đối tượng Mongo. – zakdances

+2

Bạn đang sử dụng khung web Python nào? Bạn cần vô hiệu hóa mã hóa JSON tự động hoặc tìm cách sửa đổi cách khuôn khổ mã hóa JSON. – orip

+1

Tôi đang sử dụng Kim tự tháp. Nó được thiết lập với trình kết xuất: @view_config (route_name = 'CreateNewAccount', request_method = 'GET', renderer = 'json') – zakdances

0

Bạn là dumping the string đối tượng Python (từ điển) bạn đang cung cấp.

Tài liệu hướng dẫn cho json.dumps khẳng định:

Serialize obj tới một str JSON định dạng.

Để chuyển đổi trở lại từ chuỗi, bạn sẽ cần sử dụng Python JSON function loads để LOADS một chuỗi vào đối tượng JSON.

Điều gì bạn đang cố gắng thực hiện tuy nhiên, là encode từ điển python sang JSON.

def returnJSON(color, message=None): 
    return json.encode({ "color" : color, "message" : message }) 
+0

Tôi có thể sử dụng json.encode với mặc định = json_util.default không? – zakdances

+0

Vấn đề không phải là bãi đầu tiên. Vấn đề là nó đang được mã hóa * một lần nữa * xuống dòng. –

+1

Tôi đồng ý. Nó có thể gây ra bởi dòng này: @view_config (route_name = 'CreateNewAccount', request_method = 'GET', renderer = 'json') – zakdances

1

Bạn không nói, nhưng tôi cho rằng bạn chỉ đang sử dụng mô-đun chuẩn json.

Mô-đun json không xác định một lớp cho JSON; nó sử dụng một tiêu chuẩn Python dict làm đại diện "gốc" của dữ liệu của bạn. json.dumps() mã hóa một dict dưới dạng chuỗi JSON; json.loads() nhận một chuỗi JSON và trả về một số dict.

Vì vậy, thay vì làm điều này:

def returnJSON(color, message=None): 
    return json.dumps({ "color" : "color", "message" : "message" }, default=json_util.default) 

Cố gắng làm điều này:

def returnJSON(color, message=None): 
    return { "color" : "color", "message" : "message" } 

Chỉ cần vượt qua trở lại một đồng bằng dict. Xem cách ứng dụng iPhone của bạn thích ứng dụng này.

2

Ngoài các câu trả lời xuất sắc khác, tôi muốn chỉ ra rằng nếu bạn không muốn dữ liệu được hàm xem của bạn trả về được chuyển qua json.dumps thì bạn không nên sử dụng renderer = "json" trong cấu hình xem :)

Vì vậy, thay vì

@view_config(route_name='CreateNewAccount', request_method='GET', renderer='json') 
def returnJSON(color, message=None): 
    return json.dumps({ "color" : "color", "message" : "message" }, default=json_util.default) 

bạn có thể chỉ cần sử dụng

@view_config(route_name='CreateNewAccount', request_method='GET', renderer='string') 
def returnJSON(color, message=None): 
    return json.dumps({ "color" : "color", "message" : "message" }, default=json_util.default) 

string renderer sẽ chỉ vượt qua các dữ liệu chuỗi trả về bởi bạn hàm as-is. Tuy nhiên, việc đăng ký trình kết xuất tùy chỉnh là một cách tiếp cận đẹp hơn (xem câu trả lời của orip @)

+0

Điều này đúng và đó là giải pháp tôi đang sử dụng ngay bây giờ. Tôi sẽ phải chờ đến khi Kim tự tháp 1.4 được phát hành để sử dụng trình kết xuất tùy chỉnh. – zakdances

+0

Tôi nghĩ rằng bạn đã hiểu sai tài liệu - đăng ký các trình kết xuất tùy chỉnh đã có sẵn trong Kim tự tháp trong một thời gian dài, tôi đang sử dụng trình kết xuất tùy chỉnh trong một appication kể từ khi Pyramid được gọi là repoze.bfg. http://pyramid.readthedocs.org/en/latest/narr/renderers.html#adding-a-new-renderer – Sergey

+0

Tôi cần phải cụ thể hơn ... Ý tôi là hàm JSON() để tạo tham số trình kết xuất chỉ có được thêm vào 1.4 – zakdances

Các vấn đề liên quan