【问题标题】:Python Pyramid not rendering JSON correctlyPython Pyramid 未正确呈现 JSON
【发布时间】:2014-06-26 07:13:48
【问题描述】:

我正在使用 MongoEngine 的 to_json 方法处理我希望在 json 渲染的 Pyarmid 页面中呈现的对象。我在 Pyramid 中做了很多 json 渲染,但没有使用 MongoEngine。 MongoEngine 的to_json 方法简单调用json_util.dumps。在 Python 中一切正常。问题是Pyramid在渲染页面的时候是这样渲染的:

{
  "0": "\"",
  "1": "{",
  "2": "\\",
  "3": "\"",
  "4": "_",  etc...

但是,在渲染之前,json 转储在 Python 中看起来没问题:

'{"_id": {"$oid": "4ebca43ccc7a67085b000000"}, "created": {"$date": 1346419407715}, "modified": {"$date": 1403757381829}, "modified_by": {"$oid": "4ebca43ccc7a67085b000000"}, "email":  etc...

正如 cmets 中所建议的,json 似乎不止一次被 jsonified,但我不知道在哪里。

我从数据库中取出User 对象并将其附加到每个请求中:

def get_user(request):
    return User.objects(id=ObjectId(authenticated_userid(request))).first()

config.add_request_method(get_user, 'user', reify=True)

我按要求返回用户:

@view_config(route_name='api.user', permission='authenticated', renderer='json')
def user_vc(request):
    response = request.response
    _id = request.matchdict['id']
    if _id == 'session':
        user = request.user
        if not user:
            response.status = 403
            return response
        else:
            print user  # user object as expected (not json)
            return user

我有一个自定义适配器来处理User 对象:

# custom json adapters
custom_json = JSON()

def user_adapter(obj, request):
    print obj.to_json()  # the json looks ok here
    return obj.to_json()
custom_json.add_adapter(User, user_adapter)

config.add_renderer('json', custom_json)

我自己没有做任何其他的 jsonification,除了上面的适配器。那是什么??任何帮助都会很棒。

【问题讨论】:

  • 很明显,您正在对数据进行多次 json 化。 “金字塔呈现这样的页面”看起来像 Javascript 迭代字符串对象的行为。
  • 在任何情况下,您都需要根据指南在问题中添加相关代码!
  • 谢谢@AnttiHaapala。根据您的好建议,我已经添加了相关代码。
  • Pyramid 已经有一个内置的 JSON 渲染器。是否有理由定义自己的自定义?您的视图已经配置为使用json 渲染器,因此请跳过定义您的自定义渲染器并简单地返回一个字典。 Pyramid 负责将字典呈现为 JSON。
  • 适配器应该返回一个python数据结构,而不是一个字符串。

标签: python json pyramid mongoengine


【解决方案1】:

感谢上面@AnttiHappala 的评论,我找到了问题所在。 MongoEngine 的 to_json 方法将对象转换为 jsonified 字符串。但是,Pyramid 需要一个 json 数据结构。因此,为了修复它,我在自定义渲染器中添加了以下函数:

def render_to_json(obj):
        return json.loads(obj.to_json())

    def user_adapter(obj, request):
        return render_to_json(obj)
    custom_json.add_adapter(User, user_adapter)

我现在可以为我的其他 MongoEngine 对象添加自定义渲染器并以本机方式返回它们。

【讨论】:

    猜你喜欢
    • 2012-03-23
    • 2018-06-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多