折腾:
期间,用代码:
<code>import os from datetime import datetime from flask import jsonify from flask_restful import Resource from flask_restful import reqparse from bson.objectid import ObjectId from common.FlaskLogSingleton import log from flask import g bookCollection = g.mongoCollection from conf.app import settings class xxxAPI(Resource): def get(self, bookId=None): log.info("bookId=%s, ", bookId) respDict = { "code": 200, "message": "ok", "data": {} } if not bookId: respDict = { "code": 404, "message": "Book Id can not be empty", "data": {} } log.info("respDict=%s", respDict) return jsonify(respDict) bookIdObj = ObjectId(bookId) log.info("bookIdObj=%s", bookIdObj) bookObj = bookCollection.find_one({'_id': bookIdObj}) log.info("bookObj=%s", bookObj) if not bookObj: respDict = { "code": 404, "message": "Can not find book from object id %s" % (bookId), "data": {} } return jsonify(respDict) respDict["data"] = bookIdObj return jsonify(respDict) def create_rest_api(app): from resources.storybook import xxxAPI rest_api = Api() rest_api.add_resource(xxxAPI, '/storybook/<bookId>', endpoint='storybook') rest_api.init_app(app) return rest_api </code>
然后本地调试访问url:
http://localhost:33800/storybook/5bc5e57bbfaa4425b7ea324a
结果报错:
<code>Traceback (most recent call last): File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 2309, in __call__ return self.wsgi_app(environ, start_response) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 2295, in wsgi_app response = self.handle_exception(e) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router return original_handler(e) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function return cors_after_request(app.make_response(f(*args, **kwargs))) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 1741, in handle_exception reraise(exc_type, exc_value, tb) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise raise value.with_traceback(tb) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 2292, in wsgi_app response = self.full_dispatch_request() File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 1815, in full_dispatch_request rv = self.handle_user_exception(e) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_restful/__init__.py", line 273, in error_router return original_handler(e) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_cors/extension.py", line 161, in wrapped_function return cors_after_request(app.make_response(f(*args, **kwargs))) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 1718, in handle_user_exception reraise(exc_type, exc_value, tb) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/_compat.py", line 34, in reraise raise value.with_traceback(tb) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 1813, in full_dispatch_request rv = self.dispatch_request() File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/app.py", line 1799, in dispatch_request return self.view_functions[rule.endpoint](**req.view_args) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_restful/__init__.py", line 480, in wrapper resp = resource(*args, **kwargs) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/views.py", line 88, in view return self.dispatch_request(*args, **kwargs) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask_restful/__init__.py", line 595, in dispatch_request resp = meth(*args, **kwargs) File "/Users/crifan/dev/dev_root/company/naturling/projects/xxx/server/xxx/resources/storybook.py", line 48, in get return jsonify(respDict) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/json/__init__.py", line 321, in jsonify dumps(data, indent=indent, separators=separators) + '\n', File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/json/__init__.py", line 179, in dumps rv = _json.dumps(obj, **kwargs) File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/__init__.py", line 238, in dumps **kw).encode(obj) File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 201, in encode chunks = list(chunks) File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 430, in _iterencode yield from _iterencode_dict(o, _current_indent_level) File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 404, in _iterencode_dict yield from chunks File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 437, in _iterencode o = _default(o) File "/Users/crifan/.local/share/virtualenvs/xxx-BuV5JJj8/lib/python3.6/site-packages/flask/json/__init__.py", line 81, in default return _json.JSONEncoder.default(self, o) File "/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/json/encoder.py", line 180, in default o.__class__.__name__) TypeError: Object of type 'ObjectId' is not JSON serializable </code>
flask pymongo TypeError: Object of type ‘ObjectId’ is not JSON serializable
python – TypeError: ObjectId(”) is not JSON serializable – Stack Overflow
道理上应该用Pymongo的 json_util
但是发现被人提到的这个方式更好:
去掉_id属性,然后此处自己再加上_id: idStr,更好
<code># respDict["data"] = bookObj # -> TypeError: Object of type 'ObjectId' is not JSON serializable bookDict = bookObj bookDict.pop("_id") bookDict["id"] = bookId respDict["data"] = bookDict return jsonify(respDict) </code>
调试看到返回之前的dict值:
就可以正常返回json了:
换用Chrome中JsonHandler,效果更清楚:
【总结】
此处pymongo的collection返回的单个值,是个dict,但是其中包含了特殊的:
“_id” : ObjectId(“xxx”)
导致此处Flask中用:
return jsonify(respDict)
会报错:
TypeError: Object of type ‘ObjectId’ is not JSON serializable
正常的解决办法:
使用PyMongo的json_util
http://api.mongodb.com/python/current/api/bson/json_util.html
就支持ObjectId了
此处的办法:
由于返回给用户,也不希望用到_id,只需要id,所以做法是:
去掉_id
加上id
代码:
<code># respDict["data"] = bookObj # -> TypeError: Object of type 'ObjectId' is not JSON serializable bookDict = bookObj bookDict.pop("_id") bookDict["id"] = bookId respDict["data"] = bookDict return jsonify(respDict) </code>
即可。
转载请注明:在路上 » 【已解决】Flask中返回MongoDB的collection对象出错:TypeError: Object of type ‘ObjectId’ is not JSON serializable