将日期时间序列化为整数时间戳

时间:2014-09-28 09:39:01

标签: python django-rest-framework

我希望django rest在序列化时不要将我的DateTime模型字段转换为字符串日期表示。

response_date = serializers.DateTimeField(source="updated_at")

我希望这可以作为

出现
  

1411880508

而不是

  

" 2014-09-28T05:01:48.123"

8 个答案:

答案 0 :(得分:14)

您想写一个custom serializer field,如下所示:

class TimestampField(serializers.Field):
    def to_native(self, value):
        epoch = datetime.datetime(1970,1,1)
        return int((value - epoch).total_seconds())

为了支持您希望从WritableField继承并执行from_native()的写入操作。

答案 1 :(得分:8)

REST_FRAMEWORK = {
    # if you want with milliseconds or
    'DATETIME_FORMAT': '%s.%f', 
    # only with seconds
    'DATETIME_FORMAT': '%s', 
}

REST的结果将是

1)1517863184.666435

2)1517863249

答案 2 :(得分:5)

我无法让Tom的例子工作,似乎价值没有得到修改。然而它给了我一个起点,经过一些阅读后我发现了一种产生预期结果的方法:

[方法1]

serializers.py

import time

class TimestampField(serializers.Field):
    def to_representation(self, value):
        return int(time.mktime(value.timetuple()))

class MySerializer(serializers.ModelSerializer):
    ts = TimestampField(source="my_fieldname") #Source must be a models.DateTimeField

    class Meta:
        model = myModel
        fields = ('id', 'ts')

JSON输出:

[{
    "id": 1,
    "ts": 1475894303
},
{
    "id": 2,
    "ts": 1475833070 
}]

[方法2]

汤姆的解释和之前提到的方法肯定更符合维护标准(因为结果实际上是整数类型)。

然而,快速而肮脏的解决方案是指定format parameter for the DateTimeField并将其设置为以秒为单位显示值。

请注意,这可能无法在Windows计算机上正常运行! 并且可能导致 ValueError:无效的格式字符串

要尝试一下,只需添加"格式"序列化程序字段中的关键字参数如下:

serializers.py

class MySerializer(serializers.ModelSerializer):    
    timestamp = serializers.DateTimeField(format="%s")

    class Meta:
        model = myModel
        fields = ('id', 'ts')

JSON输出:

[{
    "id": 1,
    "ts": "1475890361"
},
{
    "id": 2,
    "ts": "1475833070"
}]

此外,您可以包括微秒:

timestamp = serializers.DateTimeField(format="%s.%f")

如果您想在自己的解释器中测试功能(以验证您的操作系统是否支持%s参数),只需复制以下这些行:

import datetime
print datetime.datetime.now().strftime('%s') #datetime formatted as seconds for REST

import time  #This is just for confirmation
print time.mktime(datetime.datetime.now().timetuple()) #time object result as float

我觉得这个方法与OP问题有点不一致,因为结果实际上并不是整数类型,而是整数/浮点数的字符串表示 - 而REST会在值周围添加引号。

答案 3 :(得分:3)

全局配置:

REST_FRAMEWORK = {
    'DATETIME_FORMAT': '%s.%f',
}

答案 4 :(得分:1)

虽然我更喜欢汤姆克里斯蒂给出的答案,因为它更健壮。 为了潜在读者的利益,我决定发布我的解决方案

response_date = serializers.SerializerMethodField('get_timestamp')
def get_timestamp(self, obj):
    #times 1000 for javascript.
    return time.mktime(obj.updated_at.timetuple()) * 1000

答案 5 :(得分:1)

如前所述,您可以通过以下方式为所有日期时间设置时间戳格式:

REST_FRAMEWORK = {
    'DATETIME_FORMAT': '%s',
}

但这对于常规日期不起作用,使其适用于您必须设置的日期:

REST_FRAMEWORK = {
    'DATE_FORMAT': '%s',
}

答案 6 :(得分:0)

在python中,时间戳为10位数字。但是,在Javascript中,它是13位数字。

因此,如果要在全局配置中返回Javascript格式的时间戳,只需在'%s'之后添加'000':

JS_TIMESTAMP = '%s000'

REST_FRAMEWORK = {
    'DATETIME_FORMAT': JS_TIMESTAMP,
    'DATE_FORMAT': JS_TIMESTAMP
}

结果将如下所示:1567413479000

答案 7 :(得分:0)

感谢@megajoe 提供monkey patch solution。我在 Windows 上开发,因此得到无效的格式字符串,因为 Windows 不支持任何“%s”格式(http://msdn.microsoft.com/en-us/library/fe06s4ak.aspx)。

所以我使用了像 @megajoe 这样的猴子补丁,并稍微调整了解决方案,为“%s.%f”返回 value.timestamp(),为“%s”返回 int(value.timestamp())