[英]Bottle framework: how to return datetime in JSON response
When I try to return JSON containing datetime
value, I'm getting 当我尝试返回包含
datetime
值的JSON时,我得到了
File "/usr/lib/python2.7/json/encoder.py", line 178, in default
raise TypeError(repr(o) + " is not JSON serializable")
TypeError: datetime.datetime(2014, 2, 1, 0, 0) is not JSON serializable
Which is normal. 这是正常的。 Is there an easy way to add an object hook to
bottle
like 是否有一种简单的方法可以将对象挂钩添加到
bottle
from bson import json_util
import json
json.dumps(anObject, default=json_util.default)
to get datetime
values converted? 获取
datetime
值转换?
Interesting question! 有趣的问题! I can see a couple of ways of doing this.
我可以看到几种方法。 The one would be to write a custom plugin that wraps the
JSONPlugin
: 一个是编写一个包装
JSONPlugin
的自定义插件:
from bottle import route, run, install, JSONPlugin
from bson import json_util
class JSONDefaultPlugin(JSONPlugin):
def __init__(self):
super(JSONDefaultPlugin, self).__init__()
self.plain_dump = self.json_dumps
self.json_dumps = lambda body: self.plain_dump(body, default=json_util.default)
Which can then be used like this: 然后可以像这样使用:
@route('/hello')
def index(name):
return {'test': datetime.datetime(2014, 2, 1, 0, 0)}
install(JSONDefaultPlugin())
run(host='localhost', port=8080)
And will give output like this: 并将提供这样的输出:
{"test": {"$date": 1391212800000}}
Another, shorter, way is to simply specify the json_loads
parameter when instantiating the JSONPlugin class: 另一种更短的方法是在实例化JSONPlugin类时简单地指定
json_loads
参数:
import json
from bson import json_util
install(JSONPlugin(json_dumps=lambda body: json.dumps(body, default=json_util.default)))
This produces the same result. 这会产生相同的结果。
This all makes a little more sense when you look at the source code for bottle (some parts removed below for brevity): 当你查看瓶子的源代码时,这一切都会更有意义(为简洁起见,下面删除了一些部分):
class JSONPlugin(object):
name = 'json'
api = 2
def __init__(self, json_dumps=json_dumps):
self.json_dumps = json_dumps
def apply(self, callback, route):
dumps = self.json_dumps
if not dumps: return callback
def wrapper(*a, **ka):
...
if isinstance(rv, dict):
...
elif isinstance(rv, HTTPResponse) and isinstance(rv.body, dict):
rv.body = dumps(rv.body)
rv.content_type = 'application/json'
return rv
return wrapper
All we need to do is make sure the call to dumps
there receives the default
keyword argument you wish to provide. 我们需要做的就是确保对
dumps
的调用接收到您希望提供的default
关键字参数。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.