如何克服“datetime.datetime不支持JSON序列化”?

2024-04-25 13:45:50 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个基本的口述如下:

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere

当我试图做jsonify(sample)时,我得到:

TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable

我该怎么做才能使我的字典样本克服上述错误?

注意:虽然它可能不相关,但是字典是从mongodb中检索记录生成的,当我打印出str(sample['somedate'])时,输出是2012-08-08 21:46:24.862000


Tags: samplejsondatetimestring字典titleisnot
3条回答

在其他答案的基础上,一个基于特定序列化程序的简单解决方案,该序列化程序只将datetime.datetimedatetime.date对象转换为字符串。

from datetime import date, datetime

def json_serial(obj):
    """JSON serializer for objects not serializable by default json code"""

    if isinstance(obj, (datetime, date)):
        return obj.isoformat()
    raise TypeError ("Type %s not serializable" % type(obj))

如图所示,代码只是检查对象是否属于类datetime.datetimedatetime.date,然后使用.isoformat()根据ISO 8601格式yyy-MM-DDTHH:MM:SS(很容易被JavaScript解码)生成其序列化版本。如果寻求更复杂的序列化表示,则可以使用其他代码代替str()(有关示例,请参阅此问题的其他答案)。代码结束时引发异常,以处理使用非序列化类型调用它的情况。

这个json_串行函数可以使用如下:

from datetime import datetime
from json import dumps

print dumps(datetime.now(), default=json_serial)

json.dumps的默认参数如何工作的详细信息可以在Section Basic Usage of the json module documentation中找到。

我的快速脏JSON转储,它会吃掉日期和所有内容:

json.dumps(my_dictionary, indent=4, sort_keys=True, default=str)

2018年更新

最初的答案适应了MongoDB“date”字段的表示方式:

{"$date": 1506816000000}

如果您想要一个通用的Python解决方案来将datetime序列化为json,请查看@jjmontes' answer以获得不需要依赖项的快速解决方案。


由于您使用的是mongoengine(每个注释),而pymongo是一个依赖项,因此pymongo内置了一些实用工具来帮助进行json序列化:
http://api.mongodb.org/python/1.10.1/api/bson/json_util.html

示例用法(序列化):

from bson import json_util
import json

json.dumps(anObject, default=json_util.default)

示例用法(反序列化):

json.loads(aJsonString, object_hook=json_util.object_hook)

Django公司

Django提供了一个本地的DjangoJSONEncoder序列化程序,可以正确地处理这种类型的序列化。

https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder

from django.core.serializers.json import DjangoJSONEncoder

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  cls=DjangoJSONEncoder
)

我注意到DjangoJSONEncoder和使用自定义default之间的一个区别:

import datetime
import json

def default(o):
    if isinstance(o, (datetime.date, datetime.datetime)):
        return o.isoformat()

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  default=default
)

是不是Django删除了一点数据:

 "last_login": "2018-08-03T10:51:42.990", # DjangoJSONEncoder 
 "last_login": "2018-08-03T10:51:42.990239", # default

所以,在某些情况下你可能需要小心。

相关问题 更多 >

    热门问题