13

Django REST Framework中把DatetimeField转换为时间戳

 3 years ago
source link: https://note.qidong.name/2019/07/django-rest-datetime-to-timestamp/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Django REST Framework中把DatetimeField转换为时间戳

2019-07-21 15:32:11 +08  字数:870  标签: 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.

参考



本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可,详见本站版权声明

本站没有任何支持评论功能的计划。 如果你对本站的设计、内容、观点有什么意见,欢迎来信指正。


作者:匿蟒 邮箱:[email protected] 备案:闽ICP备15022549号


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK