关于python:Django:’datetime’类型的对象不是JSON可序列化的

Django: Object of type 'datetime' is not JSON serializable

我正试图在我的会话中保存一个日期。我总是收到错误Object of type 'datetime' is not JSON serializable。我在Django文档中找到了这个:stored as seconds since epoch since datetimes are not serializable in JSON.

如何将我的expiry_date保存为秒而不是日期时间?

1
2
3
code = social_ticketing_form.cleaned_data['a']
expiry_date = timezone.now() + timezone.timedelta(days=settings.SOCIAL_TICKETING_ATTRIBUTION_WINDOW)
request.session[social_ticketing_cookie_name(request.event)] = {'code': code, 'expiry_date': expiry_date}


要么编写自己的会话序列器,允许您直接对datetime对象进行序列化,要么以其他形式存储datetime值。

如果要将其保存为秒,则使用datetime.timestamp()方法:

1
2
3
4
request.session[social_ticketing_cookie_name(request.event)] = {
    'code': code,
    'expiry_date': expiry_date.timestamp()
}

您自己的SESSION_SERIALIZER类只需要提供loadsdumps方法,直接类似于json.loads()json.dumps()(这是标准JSON序列化程序的实现方式)。

如果要对datetime对象进行编码,并能够透明地将这些对象重新转换为datetime对象,我将使用嵌套的对象格式来标记以下值:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
from datetime import datetime

class JSONDateTimeSerializer:
    @staticmethod
    def _default(ob):
        if isinstance(ob, datetime):
            return {'__datetime__': ob.isoformat()}
        raise TypeError(type(ob))

    @staticmethod
    def _object_hook(d):
        if '__datetime__' in d:
            return datetime.fromisoformat(d['__datetime__'])
        return d

    def dumps(self, obj):
        return json.dumps(
            obj, separators=(',', ':'), default=self._default
        ).encode('latin-1')

    def loads(self, data):
        return json.loads(
            data.decode('latin-1'), object_hook=self._object_hook
        )

并将SESSION_SERIALIZER设置为上述模块的完全限定名(path.to.module.JSONDateTimeSerializer)。

上面使用的是Python3.7中新增的datetime.fromisoformat()方法。