一尘不染

使用Flask 0.10.1时获取'TypeError:ObjectId('')不可序列化JSON)

flask

我将Flask示例Minitwit与MongoDB一起使用,并且在Flask 0.9上运行良好,但是升级到0.10.1后,当我尝试设置会话ID时登录时出现标题错误。

似乎Flask 0.10.1中有与json相关的更改。

程式码片段:

user = db.minitwit.user.find_one({'username': request.form['username']})
session['_id'] = user['_id']

基本上,我将MongoDB中的Flask会话ID设置为用户的_id。

我尝试了这个SO问题的前两个解决方案,但没有成功。

好吧,执行session [‘ id’] = str(user [‘ id’])摆脱了错误消息,我已正确重定向到时间线页面,但实际上并未登录。

我怎样才能解决这个问题?


阅读 423

收藏
2020-04-07

共2个答案

一尘不染

只需将会话·保存为字符串:

user = db.minitwit.user.find_one({'username': request.form['username']})
session['_id'] = str(user['_id'])

然后,在任何你想对·进行操作的地方,都必须用ObjectId()进行包装,以便将其作为ObjectId对象传递给MongoDB。

if '_id' in session:
    g.user = db.minitwit.user.find_one({'_id': session['_id']})

至:

if '_id' in session:
    g.user = db.minitwit.user.find_one({'_id': ObjectId(session['_id'])})
2020-04-07
一尘不染

JSON默认仅支持序列化(编码/解码)一组有限的对象类型。你可以扩展python JSON的解码器/编码器来处理这种情况。

就编码包含在ObjectID上的对象而言,例如,在创建ObjectId的客户端(将其传递到等待服务器)时,请尝试:

import json
from bson.objectid import ObjectId

class Encoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, ObjectId):
            return str(obj)
        else:
            return obj

然后,在你的代码中,在推送数据客户端->服务器之前,运行:

json.dumps(obj, cls=Encoder)

服务器端,如果我们知道要处理mongo文档(带有'_id'键的字典对象),则可以定义json解码器挂钩,如下所示:

def decoder(dct):
    for k, v in dct.items():
        if '_id' in dct:
            try:
                dct['_id'] = ObjectId(dct['_id'])
            except:
                pass
        return dct

并使用如下所示的电话进行调用:

doc = json.loads(in_doc, object_hook=decoder)

你可能需要稍微修改一下此代码,但对于传递的简单情况

2020-04-07