DRF使DateTimeField无需考虑默认时区

时间:2017-04-05 10:05:03

标签: python django datetime serialization django-rest-framework

默认时区为TIME_ZONE = 'America/Chicago'USE_TZ = False

在请求数据中,我有time字段,其值如下:

'2017-04-05T14:42:52.472+05:00'

当我这样做时:

serializer = self.get_serializer(data=data)
if serializer.is_valid():
    ...

该时间字段在validated_data内转换为此内容:

2017-04-05 09:42:52.472000

也就是说,它让时间变得幼稚。但是,它没有考虑我的默认时区。我希望它首先将时间转换为芝加哥时间然后让它变得天真:

2017-04-05 04:42:52.875000

就像django.utils.timezone.make_naive()的工作方式一样。

我使用make_naive来解决这个问题。但是,我不认为这是一个很好的解决方案。

串行:

class LocationSerializer(serializers.ModelSerializer):
    time = UnixTimestampField()

    class Meta:
        model = Location
        fields = (
            'latitude',
            'longitude',
            'time'
        )

    def validate(self, attrs):
        user = self.context['request'].user
        if user.is_authenticated():
            attrs['tracking_id'] = user.tracking.id
            attrs['device_id'] = user.current_device.id
        return attrs

UnixTimestampField:

class UnixTimestampField(serializers.DateTimeField):
    def to_representation(self, value):
        if not value:
            return value

        return int(value.timestamp())

这是DRF的默认行为吗?解决这个问题的正确方法是什么?

1 个答案:

答案 0 :(得分:1)

所以我认为你对时间戳的含义有误解。

2017-04-05T14:42:52.472+05:00

这个时间戳表示比祖鲁早5个小时。所以转换后的时间戳为:

2017-04-05 09:42:52.472000

已转换为UTC,此时间戳看起来像我期望的UTC。 虽然时间戳是天真的,但它也是UTC,所以我认为不是 本身就是个问题。

  

但是,它没有考虑我的默认时区。我期待它   首先将时间转换为芝加哥时间,然后将其变为天真:

我相信这也是一种误解。原始时间戳,通过 +05:00表示它相对于哪个时区。您当地的时区不应该与它有任何关系。

一般来说,处理时间戳的正确方法是尽快将它们转换为UTC。然后尽可能将它们保持为UTC,并且仅在向用户显示时将它们转换回时区表示。如果它们必须以时间偏移量存储,那么您开始使用的格式是一个很好的方法。