2012-06-04 3 views
6

Я пытаюсь вернуть такую ​​функцию:Как настроить кодировку JSON для 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) 

Из-за собственной кодировки JSON Пирамиды, он выходит дважды закодирован так:

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

Как я могу это исправить? Мне нужно использовать default argument (или эквивалент), потому что это требуется для пользовательских типов Mongo.

+4

Это не странное форматирование. Это * нормальный * сжатый формат JSON, он использует экранированные кавычки. – VisioN

+1

@VisioN: It * есть * обычный JSON форматирование ... * для строки *. –

+0

Почему я не получаю ошибку, если я передаю прямо JSON (без JSON.dumps)? – zakdances

ответ

8

Похоже словаря быть JSON-закодирован в два раза, что эквивалентно:

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

Может быть, ваша структура Python автоматически JSON кодирует результат? Попробуйте вместо этого:

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

EDIT:

Чтобы использовать пользовательский визуализатор Pyramid, который генерирует JSON, как вы хотите, попробуйте это (на основе renderer docs и renderer sources).

В запуске:

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

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

Тогда у вас есть 'json_with_custom_default' визуализатор использовать:

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

РЕДАКТИРОВАНИЕ 2

Другой вариант мог бы вернуть Response объект, который он не должен изменять. Например.

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

Это работает, как я уже упоминал в сообщении. Мне нужно использовать JSON.dumps, потому что мне нужен default = json_util.default для сериализации объектов Mongo. – zakdances

+2

Какую веб-инфраструктуру Python вы используете? Вам необходимо отключить автоматическую кодировку JSON или найти способ изменить способ использования кодировки JSON. – orip

+1

Я использую пирамиду. Он устанавливается с помощью рендерера: @view_config (имя_пользователя = 'CreateNewAccount', request_method = 'GET', renderer = 'json') – zakdances

0

Вы - dumping the string объекта Python (словарь), который вы ему даете.

Учебное пособие для json.dumps гласит:

Serialize OBJ в формате JSON, отформатированный ул.

Чтобы преобразовать обратно из строки, вам необходимо использовать Python JSON function loads, который ЗАГРУЖАЕТ строку в объект JSON.

Однако, похоже, что вы пытаетесь сделать, это encode словарь python для JSON.

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

Можно ли использовать json.encode с default = json_util.default? – zakdances

+0

Проблема не в исходных дампах. Проблема в том, что он снова закодирован * по линии. –

+1

Согласен. Вероятно, это вызвано этой строкой: @view_config (route_name = 'CreateNewAccount', request_method = 'GET', renderer = 'json') – zakdances

1

Вы не сказали, но я предполагаю, что вы просто используете стандартный json модуль.

Модуль json не определяет класс для JSON; он использует стандартный Python dict как «собственное» представление ваших данных. json.dumps() кодирует dict как строку JSON; json.loads() берет строку JSON и возвращает dict.

Так вместо того, чтобы сделать это:

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

Попробуйте сделать это:

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

Просто передать обратно простой dict. Посмотрите, как нравится ваше приложение для iPhone.

2

В дополнение к другим отличным ответам я хотел бы указать, что если вы не хотите, чтобы данные, возвращаемые функцией просмотра, передавались через json.dumps, вы не должны использовать renderer = "json" в конфигурация вид :)

Так вместо

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

вы можете просто использовать

@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 рендер будет просто передать данные строки, возвращаемые вашим функция as-is. Тем не менее, регистрация пользовательского рендеринга является более приятным (см. Ответ @ orip)

+0

Это правда, и это решение, которое я использую сейчас. Мне придется подождать, пока Pyramid 1.4 не будет выпущен, чтобы использовать собственный рендерер. – zakdances

+0

Я думаю, что вы неправильно поняли документацию - регистрация пользовательских рендерингов была доступна в Pyramid в течение длительного времени, я использую собственный визуализатор в приложении, так как пирамида называлась repoze.bfg. http://pyramid.readthedocs.org/en/latest/narr/renderers.html#adding-a-new-renderer – Sergey

+0

Я должен был быть более конкретным ... Я имею в виду, что функция JSON() для создания параметров визуализации имеет только был добавлен в 1.4 – zakdances

Смежные вопросы