查看: 1854|回复: 4

datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable错误

[复制链接]

10

主题

82

帖子

200

积分

中级会员

Rank: 3Rank: 3

积分
200
发表于 2018-9-18 15:22:43 | 显示全部楼层 |阅读模式
我有一个基本的字典如下:
sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere
当我尝试运行的时候,我得到如下错误
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。
回复

使用道具 举报

4

主题

11

帖子

39

积分

新手上路

Rank: 1

积分
39
发表于 2018-9-18 15:23:41 | 显示全部楼层
最初的答案符合MongoDB“date”字段的表示方式:
{"$date": 1506816000000}
________________________________________
当您使用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提供了一个本地DjangoJSONEncoder序列化器来处理这种正确的。
请参阅https://docs.djangoproject.com/e ... /#djangojsonencoder
from django.core.serializers.json import DjangoJSONEncoder

return json.dumps(
  item,
  sort_keys=True,
  indent=1,
  cls=DjangoJSONEncoder
)
我注意到DjangoJSONEncoder和使用这样的自定义Encodder之间的一个区别default:
def default(o):
  if type(o) is datetime.date or type(o) is 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
因此,在某些情况下,您可能需要小心。
回复

使用道具 举报

11

主题

63

帖子

159

积分

注册会员

Rank: 2

积分
159
发表于 2018-9-18 15:24:53 | 显示全部楼层
本帖最后由 天使与魔鬼 于 2018-9-18 15:27 编辑

一个基于特定序列化器的简单解决方案,只需转换datetime.datetimedatetime.date对象到字符串。
  1. from datetime import date, datetime

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

  4.     if isinstance(obj, (datetime, date)):
  5.         return obj.isoformat()
  6.     raise TypeError ("Type %s not serializable" % type(obj))
复制代码

代码只是检查对象是否是类datetime.datetime或者datetime.date,然后用于.isoformat()生成它的序列化版本,根据ISO8601格式,YYYY-MM-DDTHHMMSS(可以通过JavaScript轻松解码) )。如果寻求更复杂的序列化表示,可以使用其他代码而不是str()(例如,参见该问题的其他答案)。代码以引发异常结束,以处理使用非可序列化类型调用的情况。
这个json_serial函数可以用如下:
  1. from datetime import datetime
  2. from json import dumps

  3. print dumps(datetime.now(), default=json_serial)
复制代码
有关如何使用json.dumps的默认参数的详细信息,请参阅json模块文档的基本用法部分


回复

使用道具 举报

9

主题

74

帖子

185

积分

注册会员

Rank: 2

积分
185
发表于 2018-9-18 15:28:57 | 显示全部楼层
  1. json.dumps(my_dictionary, indent=4, sort_keys=True, default=str)
复制代码
回复

使用道具 举报

15

主题

97

帖子

310

积分

论坛管理

Rank: 4

积分
310
发表于 2018-10-10 08:11:35 | 显示全部楼层
json序列化问题,学习了
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表