【问题标题】:Bottle framework: how to return datetime in JSON responseBottle 框架:如何在 JSON 响应中返回日期时间
【发布时间】:2014-02-12 11:00:12
【问题描述】:

当我尝试返回包含 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

这是正常的。有没有一种简单的方法可以将对象挂钩添加到bottle 喜欢

from bson import json_util
import json
json.dumps(anObject, default=json_util.default)

要转换datetime 值吗?

【问题讨论】:

  • 为什么不用datetime.strftime(o, '%Y-%m-%d %H:%M') 之类的?
  • 这个question的可能副本
  • @arocks 不,我问的是瓶子框架,它会在响应时自动将 dicts 转换为 json 数据。
  • @fp 我想通过框架工具来做到这一点。
  • 您能告诉我们您的退货方式吗?

标签: python json datetime bottle bson


【解决方案1】:

有趣的问题!我可以看到几种方法。一种是编写一个自定义插件来包装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)

然后可以这样使用:

@route('/hello')
def index(name):
    return {'test': datetime.datetime(2014, 2, 1, 0, 0)}

install(JSONDefaultPlugin())
run(host='localhost', port=8080)

并且会给出这样的输出:

{"test": {"$date": 1391212800000}}

另一种更短的方法是在实例化 JSONPlugin 类时简单地指定 json_loads 参数:

import json
from bson import json_util

install(JSONPlugin(json_dumps=lambda body: json.dumps(body, default=json_util.default)))

这会产生相同的结果。

背景

当您查看source code for bottle 时,这一切都会变得更有意义(为简洁起见,以下部分已删除):

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

我们需要做的就是确保对dumps 的调用接收到您希望提供的default 关键字参数。

【讨论】:

  • 很好的答案!我懒得看来源:-)
  • 或简称bottle.install(bottle.JSONPlugin(json_dumps=json_util.dumps))
猜你喜欢
  • 1970-01-01
  • 2023-04-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-02-19
  • 1970-01-01
  • 2021-01-05
  • 2016-04-19
相关资源
最近更新 更多