Django REST Framework中把DatetimeField转换为时间戳
2019-07-21 15:32:11 +08 字数:864 标签: django目的
普通DateTimeField
会在Django REST Framework中输出的JSON中,转换成字符串的形式,如"2019-06-10T00:49:51.689440+08:00"
。
并且也只接受对应格式字符串的输入。
这对DateField
也许还比较方便,但对DateTimeField
来说是不可接受的。
DateTimeField
只需要在显示时,由客户端(浏览器或移动App)转换为字符串,而传输时则最好是一个float
。
否则,客户端会需要比较复杂的日期与时区转换操作,传输的数据量也比较大。
本文介绍如何利用Django REST Framework中的自定义Feild
,把存储层的datetime
转换为float
形式的timestamp
。
其它方案
通过格式化,可以直接做到DateTimeField
转换为Timestamp形式的字符串,比如"1560098991.689440"
。
但是却无法做到识别这种字符串的输入,造成输入输出的不均衡。
在settings.py
中添加:
REST_FRAMEWORK = {
'DATETIME_FORMAT': '%s.%f',
'DATETIME_INPUT_FORMATS': ['%s.%f', 'iso-8601'],
}
这里输出虽然是1560098991.689440
,但是输入却必须是ISO 8601标准的"2019-06-10T00:49:51.689440+08:00"
。
那个'%s.%f'
,输出时没问题,输入时却会被解析为ss.uuuuuu
的形式,丢失了秒以上的信息。
也就是说,只能输入"91.689440"
这种字符串,时间当然不对。
可行方案
利用Django REST Framework中的自定义Field
,可以在存储层的datetime
和表现层的timestamp
之间做转换。
Model样例
from django.db.models import DateTimeField, Model
class Example(Model):
datetime = DateTimeField()
Serializers
from datetime import datetime
from pytz import timezone
from rest_framework.serializers import Field, HyperlinkedModelSerializer
from ..settings import TIME_ZONE
class TimestampField(Field):
"""
This serializer field transform a datetime str to a timestamp float.
"""
def to_representation(self, value):
return value.timestamp()
def to_internal_value(self, data):
timestamp = float(data)
no_tz = datetime.utcfromtimestamp(timestamp)
return no_tz.astimezone(timezone(TIME_ZONE))
class ExampleSerializer(HyperlinkedModelSerializer):
timestamp = TimestampField(source='datetime')
class Meta:
model = Frame
fields = (
'url',
'timestamp',
)
如果不在datetime
中放入时区信息,则会有以下警告:
RuntimeWarning: DateTimeField Frame.datetime received a naive datetime (2019-06-09 16:49:51.689440) while time zone support is active.