我将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’])摆脱了错误消息,我已正确重定向到时间线页面,但实际上并未登录。
我怎样才能解决这个问题?
只需将会话·保存为字符串:
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'])})
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解码器挂钩,如下所示:
'_id'
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)
你可能需要稍微修改一下此代码,但对于传递的简单情况