在这里查看文档:http://www.django-rest-framework.org/api-guide/fields/#datetimefield
签名:DateTimeField(format=None, input_formats=None)
format - 表示输出格式的字符串。如果未指定,则默认为与 DATETIME_FORMAT 设置键相同的值,除非设置,否则将为“iso-8601”。设置为格式字符串表示 to_representation 返回值应强制转换为字符串输出。格式字符串如下所述。将此值设置为 None 表示 Python 日期时间对象应由 to_representation 返回。在这种情况下,日期时间编码将由渲染器确定。
当格式使用 None 值时,to_representation 将返回对象,最终输出表示将由渲染器类确定。
对于 JSON,这意味着默认日期时间表示使用 ECMA 262 日期时间字符串规范。这是使用毫秒精度的 ISO 8601 的子集,包括 UTC 时区的“Z”后缀,例如:2013-01-29T12:34:56.123Z。
因此,获取日期时间对象的 UTC (Z) 表示实际上是默认行为。
当您通过 Djangorest 创建 或 更新 模型实例时,将使用 data kwarg 调用序列化程序,如果您使用列表则不会发生这种情况或详细视图。
在这两种情况下,您的视图都将返回 serializer.data。在 create/update 操作的情况下,这将是 serializer.validated_data 的表示,而在 list/detail 操作的情况下,它将直接表示实例。
在这两种情况下,表示是通过使用默认 kwarg format=None 调用 field.to_representation 来实现的,这将使该字段返回纯字符串值。
奇迹发生了here:
-
create/update:验证返回一个时区感知对象,其中包括您的标准时区。通过调用其
isoformat() 方法将其转换为字符串,并按原样返回。
-
list/retrieve:django ORM 将时间戳存储为 UTC。通过调用其
isoformat() 方法将其转换为字符串,但DRF 将+00:00 替换为Z(参见上面的链接)。
因此,要获得带有时区偏移的所需输出,您可以将 format=None 或自定义 strftime 字符串传递给序列化程序中的 DateTimeField。但是,您将始终使用+00:00 获得 UTC 时间,因为(幸运的是)数据就是这样存储的。
如果您想要'Asia/Kolkata' 的实际偏移量,您可能必须定义自己的DateTimeField:
from django.utils import timezone
class CustomDateTimeField(serializers.DateTimeField):
def to_representation(self, value):
tz = timezone.get_default_timezone()
# timezone.localtime() defaults to the current tz, you only
# need the `tz` arg if the current tz != default tz
value = timezone.localtime(value, timezone=tz)
# py3 notation below, for py2 do:
# return super(CustomDateTimeField, self).to_representation(value)
return super().to_representation(value)