Как настроить кодировку 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)

из-за собственной JSON-кодировки Pyramid, она выходит двойной кодировкой, как это:

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

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

4 ответов


похоже, что словарь кодируется JSON дважды, что эквивалентно:

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

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

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

EDIT:

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

In запуск:

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

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

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


вы не сказали, но я предполагаю, что вы просто используете стандартный 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.


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

руководство для json.dumps заявляет:

сериализовать obj для STR в формате JSON.

чтобы преобразовать обратно из строки, вам нужно будет использовать функция Python JSON загружает который загружает строку в объект JSON.

то, что вы пытаетесь сделать, однако, является encode питон словарь в JSON.

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