【问题标题】:How can I configure Pyramid's JSON encoding?如何配置 Pyramid 的 JSON 编码?
【发布时间】:2012-06-08 21:09:20
【问题描述】:

我正在尝试返回这样的函数:

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

由于 Pyramid 自己的 JSON 编码,它会像这样进行双重编码:

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

我该如何解决这个问题?我需要使用 default argument(或等效的),因为它是 Mongo 的自定义类型所必需的。

【问题讨论】:

  • 这不是一个奇怪的格式。这是一种普通字符串化的 JSON 格式,它使用转义引号。
  • @VisioN:它普通的 JSON 格式...对于字符串
  • 如果我直接传入 JSON(没有 JSON.dumps),为什么我没有收到错误消息?
  • 顺便说一句,您没有将 colormessage 参数传递到您的 json 字典中。
  • 有谁知道我如何取消转义/取消字符串化?

标签: python json pyramid pymongo


【解决方案1】:

除了其他出色的答案,我想指出,如果您不希望视图函数返回的数据通过 json.dumps 传递,那么您不应该在查看配置:)

所以不是

@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 渲染器将按原样传递函数返回的字符串数据。但是,注册自定义渲染器是一种更好的方法(请参阅@orip 的答案)

【讨论】:

  • 这是真的,这是我现在使用的解决方案。我必须等到 Pyramid 1.4 发布才能使用自定义渲染器。
  • 我认为你误读了文档——注册自定义渲染器已经在 Pyramid 中提供了很长时间,自从 Pyramid 被称为 repoze.bfg 以来,我一直在应用程序中使用自定义渲染器。 pyramid.readthedocs.org/en/latest/narr/…
  • 我应该更具体...我的意思是用于创建渲染器参数的 JSON() 函数仅在 1.4 中添加
【解决方案2】:

字典似乎被 JSON 编码了两次,相当于:

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

也许您的 Python 框架会自动对结果进行 JSON 编码?试试这个:

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

编辑:

要使用自定义 Pyramid 渲染器以您想要的方式生成 JSON,请尝试此方法(基于 renderer docsrenderer 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)

【讨论】:

  • 这行得通,就像我在帖子中提到的那样。我需要使用 JSON.dumps,因为我需要 default=json_util.default 来序列化 Mongo 对象。
  • 您使用的是哪个 Python Web 框架?您需要禁用自动 JSON 编码,或者想办法修改框架进行 JSON 编码的方式。
  • 我正在使用金字塔。它使用渲染器设置:@view_config(route_name='CreateNewAccount', request_method='GET', renderer='json')
  • 添加了 Pyramid 自定义渲染器的示例代码和链接,也许这会对您有所帮助
  • (1) 可能是您需要from pyramid.renderers import JSON。 (2) JSON 类将其构造函数中给出的关键字参数转发给 json.dumps 函数(参见我链接的源代码),因此使用 default=json_util.default 创建 JSON 的实例应该使用正确的选项。 (3) 如果这不起作用,请尝试像开始一样自己在 JSON 中编码,但将其包装在 Response 中以防止任何渲染器修改它。您可能必须自己设置内容类型和其他 HTTP 标头。
【解决方案3】:

你没有说,但我假设你只是使用标准的 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 应用喜欢这个。

【讨论】:

    【解决方案4】:

    您是您提供给它的 Python 对象(字典)的 dumping the string

    json.dumps 的手册说明:

    将 obj 序列化为 JSON 格式的 str。

    要从字符串转换回来,您需要使用 Python JSON function loads 将字符串加载到 JSON 对象中。

    但是,您似乎正在尝试做的是 encode 到 JSON 的 python 字典。

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

    【讨论】:

    • 问题不在于初始转储。问题是它正在被再次编码。
    • 我同意。它可能是由这一行引起的:@view_config(route_name='CreateNewAccount', request_method='GET', renderer='json')
    • @MatthewFlaschen 是正确的......现在我需要弄清楚如何禁用它
    • @yourfriendzak,这现在真的是一个 Pyramid 和 pymongo 问题,所以你应该相应地编辑它。我给了你一个开始。
    猜你喜欢
    • 2017-01-26
    • 2011-11-26
    • 2015-02-14
    • 2015-08-18
    • 1970-01-01
    • 2015-12-13
    • 2011-10-31
    • 2011-03-02
    • 2013-06-12
    相关资源
    最近更新 更多